diff options
author | Octavian Purdila <opurdila@ixiacom.com> | 2009-12-26 06:50:59 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-26 23:38:23 -0500 |
commit | bf9ae5386bca8836c16e69ab8fdbe46767d7452a (patch) | |
tree | 1184d7062dd74f7ad2b85379a5bd40ab5b8ca4d6 /net/llc/llc_output.c | |
parent | f83d664eef180478c2dc0a0099e9d7bc1c8177ff (diff) |
llc: use dev_hard_header
Using dev_hard_header allows us to use LLC with VLANs and potentially
other Ethernet/TokernRing specific encapsulations. It also removes code
duplication between LLC and Ethernet/TokenRing core code.
Signed-off-by: Octavian Purdila <opurdila@ixiacom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/llc/llc_output.c')
-rw-r--r-- | net/llc/llc_output.c | 45 |
1 files changed, 8 insertions, 37 deletions
diff --git a/net/llc/llc_output.c b/net/llc/llc_output.c index 754f4fedc85..b38a1079a98 100644 --- a/net/llc/llc_output.c +++ b/net/llc/llc_output.c | |||
@@ -33,48 +33,19 @@ | |||
33 | int llc_mac_hdr_init(struct sk_buff *skb, | 33 | int llc_mac_hdr_init(struct sk_buff *skb, |
34 | const unsigned char *sa, const unsigned char *da) | 34 | const unsigned char *sa, const unsigned char *da) |
35 | { | 35 | { |
36 | int rc = 0; | 36 | int rc = -EINVAL; |
37 | 37 | ||
38 | switch (skb->dev->type) { | 38 | switch (skb->dev->type) { |
39 | #ifdef CONFIG_TR | 39 | case ARPHRD_IEEE802_TR: |
40 | case ARPHRD_IEEE802_TR: { | ||
41 | struct net_device *dev = skb->dev; | ||
42 | struct trh_hdr *trh; | ||
43 | |||
44 | skb_push(skb, sizeof(*trh)); | ||
45 | skb_reset_mac_header(skb); | ||
46 | trh = tr_hdr(skb); | ||
47 | trh->ac = AC; | ||
48 | trh->fc = LLC_FRAME; | ||
49 | if (sa) | ||
50 | memcpy(trh->saddr, sa, dev->addr_len); | ||
51 | else | ||
52 | memset(trh->saddr, 0, dev->addr_len); | ||
53 | if (da) { | ||
54 | memcpy(trh->daddr, da, dev->addr_len); | ||
55 | tr_source_route(skb, trh, dev); | ||
56 | skb_reset_mac_header(skb); | ||
57 | } | ||
58 | break; | ||
59 | } | ||
60 | #endif | ||
61 | case ARPHRD_ETHER: | 40 | case ARPHRD_ETHER: |
62 | case ARPHRD_LOOPBACK: { | 41 | case ARPHRD_LOOPBACK: |
63 | unsigned short len = skb->len; | 42 | rc = dev_hard_header(skb, skb->dev, ETH_P_802_2, da, sa, |
64 | struct ethhdr *eth; | 43 | skb->len); |
65 | 44 | if (rc > 0) | |
66 | skb_push(skb, sizeof(*eth)); | 45 | rc = 0; |
67 | skb_reset_mac_header(skb); | ||
68 | eth = eth_hdr(skb); | ||
69 | eth->h_proto = htons(len); | ||
70 | memcpy(eth->h_dest, da, ETH_ALEN); | ||
71 | memcpy(eth->h_source, sa, ETH_ALEN); | ||
72 | break; | 46 | break; |
73 | } | ||
74 | default: | 47 | default: |
75 | printk(KERN_WARNING "device type not supported: %d\n", | 48 | WARN(1, "device type not supported: %d\n", skb->dev->type); |
76 | skb->dev->type); | ||
77 | rc = -EINVAL; | ||
78 | } | 49 | } |
79 | return rc; | 50 | return rc; |
80 | } | 51 | } |