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 | |
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')
-rw-r--r-- | net/8021q/vlan_dev.c | 7 | ||||
-rw-r--r-- | net/ethernet/eth.c | 6 | ||||
-rw-r--r-- | net/llc/llc_output.c | 45 |
3 files changed, 14 insertions, 44 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index b7889782047..77a49ffdd0e 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -263,11 +263,10 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, | |||
263 | vhdr->h_vlan_TCI = htons(vlan_tci); | 263 | vhdr->h_vlan_TCI = htons(vlan_tci); |
264 | 264 | ||
265 | /* | 265 | /* |
266 | * Set the protocol type. For a packet of type ETH_P_802_3 we | 266 | * Set the protocol type. For a packet of type ETH_P_802_3/2 we |
267 | * put the length in here instead. It is up to the 802.2 | 267 | * put the length in here instead. |
268 | * layer to carry protocol information. | ||
269 | */ | 268 | */ |
270 | if (type != ETH_P_802_3) | 269 | if (type != ETH_P_802_3 && type != ETH_P_802_2) |
271 | vhdr->h_vlan_encapsulated_proto = htons(type); | 270 | vhdr->h_vlan_encapsulated_proto = htons(type); |
272 | else | 271 | else |
273 | vhdr->h_vlan_encapsulated_proto = htons(len); | 272 | vhdr->h_vlan_encapsulated_proto = htons(len); |
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index dd3db88f8f0..205a1c12f3c 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c | |||
@@ -73,8 +73,8 @@ __setup("ether=", netdev_boot_setup); | |||
73 | * @len: packet length (<= skb->len) | 73 | * @len: packet length (<= skb->len) |
74 | * | 74 | * |
75 | * | 75 | * |
76 | * Set the protocol type. For a packet of type ETH_P_802_3 we put the length | 76 | * Set the protocol type. For a packet of type ETH_P_802_3/2 we put the length |
77 | * in here instead. It is up to the 802.2 layer to carry protocol information. | 77 | * in here instead. |
78 | */ | 78 | */ |
79 | int eth_header(struct sk_buff *skb, struct net_device *dev, | 79 | int eth_header(struct sk_buff *skb, struct net_device *dev, |
80 | unsigned short type, | 80 | unsigned short type, |
@@ -82,7 +82,7 @@ int eth_header(struct sk_buff *skb, struct net_device *dev, | |||
82 | { | 82 | { |
83 | struct ethhdr *eth = (struct ethhdr *)skb_push(skb, ETH_HLEN); | 83 | struct ethhdr *eth = (struct ethhdr *)skb_push(skb, ETH_HLEN); |
84 | 84 | ||
85 | if (type != ETH_P_802_3) | 85 | if (type != ETH_P_802_3 && type != ETH_P_802_2) |
86 | eth->h_proto = htons(type); | 86 | eth->h_proto = htons(type); |
87 | else | 87 | else |
88 | eth->h_proto = htons(len); | 88 | eth->h_proto = htons(len); |
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 | } |