* [PATCH] net: packet: option to only pass skb protocol @ 2010-01-05 18:57 Michael S. Tsirkin 2010-01-05 19:27 ` Eric Dumazet 2010-01-05 21:28 ` Chris Friesen 0 siblings, 2 replies; 15+ messages in thread From: Michael S. Tsirkin @ 2010-01-05 18:57 UTC (permalink / raw) To: David S. Miller, Eric Dumazet, Neil Horman, linux-kernel, netdev When sending packets with a packet socket it is often necessary to set protocol in msg_name: otherwise the protocol field in the skb will not be set correctly. However, currently doing this also requires supplying the interface index. The following patch makes it possible to avoid supplying the interface index by interpreting index 0 as "use device this socket is bound to". Signed-off-by: Michael S. Tsirkin <mst@redhat.com> --- net/packet/af_packet.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index e0516a2..a81dae8 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -958,7 +958,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) + offsetof(struct sockaddr_ll, sll_addr))) goto out; - ifindex = saddr->sll_ifindex; + ifindex = saddr->sll_ifindex ? : po->ifindex; proto = saddr->sll_protocol; addr = saddr->sll_addr; } @@ -1074,7 +1074,7 @@ static int packet_snd(struct socket *sock, goto out; if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) goto out; - ifindex = saddr->sll_ifindex; + ifindex = saddr->sll_ifindex ? : po->ifindex; proto = saddr->sll_protocol; addr = saddr->sll_addr; } -- 1.6.6.rc1.43.gf55cc ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH] net: packet: option to only pass skb protocol 2010-01-05 18:57 [PATCH] net: packet: option to only pass skb protocol Michael S. Tsirkin @ 2010-01-05 19:27 ` Eric Dumazet 2010-01-05 20:50 ` Michael S. Tsirkin 2010-01-05 21:28 ` Chris Friesen 1 sibling, 1 reply; 15+ messages in thread From: Eric Dumazet @ 2010-01-05 19:27 UTC (permalink / raw) To: Michael S. Tsirkin; +Cc: David S. Miller, Neil Horman, linux-kernel, netdev Le 05/01/2010 19:57, Michael S. Tsirkin a écrit : > When sending packets with a packet socket it is often necessary to set > protocol in msg_name: otherwise the protocol field in the skb will not > be set correctly. However, currently doing this also requires > supplying the interface index. > > The following patch makes it possible to avoid supplying the interface > index by interpreting index 0 as "use device this socket is bound to". > Patch is correct, but I dont understand why zero initialization by caller is any better then supplying ifindex (known when socket was bound to device ?) To avoid one syscall at socket setup (to get ifindex from dev name), you prefer to add a test/branch at each send() syscall... Am I missing something ? ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] net: packet: option to only pass skb protocol 2010-01-05 19:27 ` Eric Dumazet @ 2010-01-05 20:50 ` Michael S. Tsirkin 2010-01-05 21:40 ` David Miller 0 siblings, 1 reply; 15+ messages in thread From: Michael S. Tsirkin @ 2010-01-05 20:50 UTC (permalink / raw) To: Eric Dumazet; +Cc: David S. Miller, Neil Horman, linux-kernel, netdev On Tue, Jan 05, 2010 at 08:27:21PM +0100, Eric Dumazet wrote: > Le 05/01/2010 19:57, Michael S. Tsirkin a écrit : > > When sending packets with a packet socket it is often necessary to set > > protocol in msg_name: otherwise the protocol field in the skb will not > > be set correctly. However, currently doing this also requires > > supplying the interface index. > > > > The following patch makes it possible to avoid supplying the interface > > index by interpreting index 0 as "use device this socket is bound to". > > > > Patch is correct, but I dont understand why zero initialization by caller > is any better then supplying ifindex (known when socket was bound to device ?) > > To avoid one syscall at socket setup (to get ifindex from dev name), > you prefer to add a test/branch at each send() syscall... > > Am I missing something ? binding socket to device might be done by a separate process from the one doing sendmsg, and IMO the device socket is bound to might change at any time. So the sending process would need to get socket name before each sendmsg. Makes sense? -- MST ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] net: packet: option to only pass skb protocol 2010-01-05 20:50 ` Michael S. Tsirkin @ 2010-01-05 21:40 ` David Miller 2010-01-05 21:50 ` Michael S. Tsirkin 0 siblings, 1 reply; 15+ messages in thread From: David Miller @ 2010-01-05 21:40 UTC (permalink / raw) To: mst; +Cc: eric.dumazet, nhorman, linux-kernel, netdev From: "Michael S. Tsirkin" <mst@redhat.com> Date: Tue, 5 Jan 2010 22:50:40 +0200 > binding socket to device might be done by a separate process > from the one doing sendmsg, and IMO the device socket is bound > to might change at any time. > > So the sending process would need to get socket name before > each sendmsg. > > Makes sense? Not really, when it's at the expense of everyone else. If you can pass the FD around, you can pass around auxiliary information as well. Make sense? :-) ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] net: packet: option to only pass skb protocol 2010-01-05 21:40 ` David Miller @ 2010-01-05 21:50 ` Michael S. Tsirkin 0 siblings, 0 replies; 15+ messages in thread From: Michael S. Tsirkin @ 2010-01-05 21:50 UTC (permalink / raw) To: David Miller; +Cc: eric.dumazet, nhorman, linux-kernel, netdev On Tue, Jan 05, 2010 at 01:40:38PM -0800, David Miller wrote: > From: "Michael S. Tsirkin" <mst@redhat.com> > Date: Tue, 5 Jan 2010 22:50:40 +0200 > > > binding socket to device might be done by a separate process > > from the one doing sendmsg, and IMO the device socket is bound > > to might change at any time. > > > > So the sending process would need to get socket name before > > each sendmsg. > > > > Makes sense? > > Not really, when it's at the expense of everyone else. > > If you can pass the FD around, you can pass around auxiliary > information as well. > > Make sense? :-) At some level, of course I can. But I would have to do this communication each time socket is bound to another device, as opposed to passing the fd once. At least for me, option to autodetect protocol would work even better though - it's what I do in the application anyway. -- MST ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] net: packet: option to only pass skb protocol 2010-01-05 18:57 [PATCH] net: packet: option to only pass skb protocol Michael S. Tsirkin 2010-01-05 19:27 ` Eric Dumazet @ 2010-01-05 21:28 ` Chris Friesen 2010-01-05 21:42 ` David Miller 1 sibling, 1 reply; 15+ messages in thread From: Chris Friesen @ 2010-01-05 21:28 UTC (permalink / raw) To: Michael S. Tsirkin Cc: David S. Miller, Eric Dumazet, Neil Horman, linux-kernel, netdev On 01/05/2010 12:57 PM, Michael S. Tsirkin wrote: > When sending packets with a packet socket it is often necessary to set > protocol in msg_name: otherwise the protocol field in the skb will not > be set correctly. What about automatically detecting the protocol from the data being sent to avoid the necessity of specifying it in the first place? Chris ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] net: packet: option to only pass skb protocol 2010-01-05 21:28 ` Chris Friesen @ 2010-01-05 21:42 ` David Miller 2010-01-05 21:45 ` Michael S. Tsirkin 2010-01-05 22:13 ` Chris Friesen 0 siblings, 2 replies; 15+ messages in thread From: David Miller @ 2010-01-05 21:42 UTC (permalink / raw) To: cfriesen; +Cc: mst, eric.dumazet, nhorman, linux-kernel, netdev From: "Chris Friesen" <cfriesen@nortel.com> Date: Tue, 05 Jan 2010 15:28:22 -0600 > On 01/05/2010 12:57 PM, Michael S. Tsirkin wrote: >> When sending packets with a packet socket it is often necessary to set >> protocol in msg_name: otherwise the protocol field in the skb will not >> be set correctly. > > What about automatically detecting the protocol from the data being sent > to avoid the necessity of specifying it in the first place? This limits packet socket usage to only protocols the kernel is aware of, defeating part of the usefulness of the packet socket facility. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] net: packet: option to only pass skb protocol 2010-01-05 21:42 ` David Miller @ 2010-01-05 21:45 ` Michael S. Tsirkin 2010-01-05 22:05 ` Michael S. Tsirkin 2010-01-05 22:13 ` Chris Friesen 1 sibling, 1 reply; 15+ messages in thread From: Michael S. Tsirkin @ 2010-01-05 21:45 UTC (permalink / raw) To: David Miller; +Cc: cfriesen, eric.dumazet, nhorman, linux-kernel, netdev On Tue, Jan 05, 2010 at 01:42:18PM -0800, David Miller wrote: > From: "Chris Friesen" <cfriesen@nortel.com> > Date: Tue, 05 Jan 2010 15:28:22 -0600 > > > On 01/05/2010 12:57 PM, Michael S. Tsirkin wrote: > >> When sending packets with a packet socket it is often necessary to set > >> protocol in msg_name: otherwise the protocol field in the skb will not > >> be set correctly. > > > > What about automatically detecting the protocol from the data being sent > > to avoid the necessity of specifying it in the first place? > > This limits packet socket usage to only protocols the kernel is aware > of, defeating part of the usefulness of the packet socket facility. We could do this if the protocol is ETH_P_ALL - skbs end up with this protocol currently when sendmsg does not have msgname and when socket is set up to listen for all packets. It's not a valid protocol value, is it? -- MST ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] net: packet: option to only pass skb protocol 2010-01-05 21:45 ` Michael S. Tsirkin @ 2010-01-05 22:05 ` Michael S. Tsirkin 0 siblings, 0 replies; 15+ messages in thread From: Michael S. Tsirkin @ 2010-01-05 22:05 UTC (permalink / raw) To: David Miller; +Cc: cfriesen, eric.dumazet, nhorman, linux-kernel, netdev On Tue, Jan 05, 2010 at 11:45:24PM +0200, Michael S. Tsirkin wrote: > On Tue, Jan 05, 2010 at 01:42:18PM -0800, David Miller wrote: > > From: "Chris Friesen" <cfriesen@nortel.com> > > Date: Tue, 05 Jan 2010 15:28:22 -0600 > > > > > On 01/05/2010 12:57 PM, Michael S. Tsirkin wrote: > > >> When sending packets with a packet socket it is often necessary to set > > >> protocol in msg_name: otherwise the protocol field in the skb will not > > >> be set correctly. > > > > > > What about automatically detecting the protocol from the data being sent > > > to avoid the necessity of specifying it in the first place? > > > > This limits packet socket usage to only protocols the kernel is aware > > of, defeating part of the usefulness of the packet socket facility. > > We could do this if the protocol is ETH_P_ALL - skbs end up with this > protocol currently when sendmsg does not have msgname and when socket is > set up to listen for all packets. It's not a valid protocol value, is > it? Something like this (if we want to support this for all device types, we would probably need to add get_proto callback to net_device_ops), and call it instead of eth_hdr(skb)->h_proto. diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index a81dae8..a23d4b2 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -845,7 +845,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, ph.raw = frame; - skb->protocol = proto; skb->dev = dev; skb->priority = po->sk.sk_priority; skb->mark = po->sk.sk_mark; @@ -924,6 +923,11 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, len = ((to_write > len_max) ? len_max : to_write); } + if (proto == htons(ETH_P_ALL) && dev->type == ARPHRD_ETHER) + skb->protocol = eth_hdr(skb)->h_proto; + else + skb->protocol = proto; + return tp_len; } @@ -1113,7 +1117,10 @@ static int packet_snd(struct socket *sock, if (err) goto out_free; - skb->protocol = proto; + if (proto == htons(ETH_P_ALL) && dev->type == ARPHRD_ETHER) + skb->protocol = eth_hdr(skb)->h_proto; + else + skb->protocol = proto; skb->dev = dev; skb->priority = sk->sk_priority; skb->mark = sk->sk_mark; ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH] net: packet: option to only pass skb protocol 2010-01-05 21:42 ` David Miller 2010-01-05 21:45 ` Michael S. Tsirkin @ 2010-01-05 22:13 ` Chris Friesen 2010-01-05 22:27 ` Michael S. Tsirkin 2010-01-05 23:51 ` David Miller 1 sibling, 2 replies; 15+ messages in thread From: Chris Friesen @ 2010-01-05 22:13 UTC (permalink / raw) To: David Miller; +Cc: mst, eric.dumazet, nhorman, linux-kernel, netdev On 01/05/2010 03:42 PM, David Miller wrote: > From: "Chris Friesen" <cfriesen@nortel.com> > Date: Tue, 05 Jan 2010 15:28:22 -0600 > >> On 01/05/2010 12:57 PM, Michael S. Tsirkin wrote: >>> When sending packets with a packet socket it is often necessary to set >>> protocol in msg_name: otherwise the protocol field in the skb will not >>> be set correctly. >> >> What about automatically detecting the protocol from the data being sent >> to avoid the necessity of specifying it in the first place? > > This limits packet socket usage to only protocols the kernel is aware > of, defeating part of the usefulness of the packet socket facility. I don't follow. If SOCK_RAW packets are being sent, the protocol number is embedded in the packet data and the kernel should be able to extract it regardless of whether the kernel actually supports it or not. I see that Michael just posted a patch for this. If SOCK_DGRAM packets are being sent, then I agree that the app needs to pass it down at send time or at bind() time to support protocols of which the kernel is not aware. While looking at the code I noticed that while the protocol number is validated at socket creation time it does not appear to be validated for calls to bind() for packet sockets. Is this intentional? As a further question, does it actually make sense to check the protocol number at packet socket creation? It seems like we should be able to allow a packet socket to specify arbitrary protocol numbers since the kernel doesn't really need to do anything with them. Chris ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] net: packet: option to only pass skb protocol 2010-01-05 22:13 ` Chris Friesen @ 2010-01-05 22:27 ` Michael S. Tsirkin 2010-01-05 23:51 ` David Miller 1 sibling, 0 replies; 15+ messages in thread From: Michael S. Tsirkin @ 2010-01-05 22:27 UTC (permalink / raw) To: Chris Friesen; +Cc: David Miller, eric.dumazet, nhorman, linux-kernel, netdev On Tue, Jan 05, 2010 at 04:13:29PM -0600, Chris Friesen wrote: > On 01/05/2010 03:42 PM, David Miller wrote: > > From: "Chris Friesen" <cfriesen@nortel.com> > > Date: Tue, 05 Jan 2010 15:28:22 -0600 > > > >> On 01/05/2010 12:57 PM, Michael S. Tsirkin wrote: > >>> When sending packets with a packet socket it is often necessary to set > >>> protocol in msg_name: otherwise the protocol field in the skb will not > >>> be set correctly. > >> > >> What about automatically detecting the protocol from the data being sent > >> to avoid the necessity of specifying it in the first place? > > > > This limits packet socket usage to only protocols the kernel is aware > > of, defeating part of the usefulness of the packet socket facility. > > I don't follow. > > If SOCK_RAW packets are being sent, the protocol number is embedded in > the packet data and the kernel should be able to extract it regardless > of whether the kernel actually supports it or not. I see that Michael > just posted a patch for this. > > If SOCK_DGRAM packets are being sent, then I agree that the app needs to > pass it down at send time or at bind() time to support protocols of > which the kernel is not aware. > > While looking at the code I noticed that while the protocol number is > validated at socket creation time it does not appear to be validated for > calls to bind() for packet sockets. Is this intentional? > > As a further question, does it actually make sense to check the protocol > number at packet socket creation? It seems like we should be able to > allow a packet socket to specify arbitrary protocol numbers since the > kernel doesn't really need to do anything with them. > > Chris I wouldn't say kernel doesn't really need to do anything with them. In fact I think currently protocol number affects whether other packet sockets see the packet in question. There may be other cases, e.g. if the device in question is a bridge, the packet gets reinjected in host stack, so using a silly value for protocol field might interfere with GRO etc. -- MST ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] net: packet: option to only pass skb protocol 2010-01-05 22:13 ` Chris Friesen 2010-01-05 22:27 ` Michael S. Tsirkin @ 2010-01-05 23:51 ` David Miller 2010-01-06 9:12 ` Michael S. Tsirkin 1 sibling, 1 reply; 15+ messages in thread From: David Miller @ 2010-01-05 23:51 UTC (permalink / raw) To: cfriesen; +Cc: mst, eric.dumazet, nhorman, linux-kernel, netdev From: "Chris Friesen" <cfriesen@nortel.com> Date: Tue, 05 Jan 2010 16:13:29 -0600 > If SOCK_RAW packets are being sent, the protocol number is embedded in > the packet data Where exactly is that protocol value? Not every link level protocol is ethernet. We support FDDI, HIPPI, wireless, VLAN, PPP, and a host of others. So you can't know for sure unless you assume ethernet, which you can't do. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] net: packet: option to only pass skb protocol 2010-01-05 23:51 ` David Miller @ 2010-01-06 9:12 ` Michael S. Tsirkin 2010-01-06 19:24 ` Michael S. Tsirkin 2010-01-07 8:27 ` Michał Mirosław 0 siblings, 2 replies; 15+ messages in thread From: Michael S. Tsirkin @ 2010-01-06 9:12 UTC (permalink / raw) To: David Miller; +Cc: cfriesen, eric.dumazet, nhorman, linux-kernel, netdev On Tue, Jan 05, 2010 at 03:51:50PM -0800, David Miller wrote: > From: "Chris Friesen" <cfriesen@nortel.com> > Date: Tue, 05 Jan 2010 16:13:29 -0600 > > > If SOCK_RAW packets are being sent, the protocol number is embedded in > > the packet data > > Where exactly is that protocol value? Not every link level protocol > is ethernet. > > We support FDDI, HIPPI, wireless, VLAN, PPP, and a host of others. > > So you can't know for sure unless you assume ethernet, which you > can't do. You are right. This is TX though so the socket is bound to a specific device, and devices know which link protocol they use. So we could add a get_protocol operation to each device type, and call it if the protocol passed is ETH_P_ALL to get the real one. Like this: except I only added this for ethernet, and I would have to add this for the rest of device types. But I would like to hear what others think about this before I do the rest of the work for the rest of device types. Does the below look sane? diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index a3fccc8..99d7801 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -319,6 +319,7 @@ struct header_ops { void (*cache_update)(struct hh_cache *hh, const struct net_device *dev, const unsigned char *haddr); + __be16 (*get_protocol)(struct sk_buff *skb, struct net_device *dev) }; /* These flag bits are private to the generic network queueing diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 205a1c1..3e7761d 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -231,6 +231,17 @@ int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr) EXPORT_SYMBOL(eth_header_parse); /** + * eth_get_protocol - extract protocol value from packet + * @skb: packet to extract protocol from + * @dev: source device + */ +__be16 eth_get_protocol(const struct sk_buff *skb, struct net_device *dev) +{ + const struct ethhdr *eth = eth_hdr(skb); + return eth->h_proto +} + +/** * eth_header_cache - fill cache entry from neighbour * @neigh: source neighbour * @hh: destination cache entry @@ -324,6 +335,7 @@ EXPORT_SYMBOL(eth_validate_addr); const struct header_ops eth_header_ops ____cacheline_aligned = { .create = eth_header, .parse = eth_header_parse, + .get_protocol = eth_get_protocol, .rebuild = eth_rebuild_header, .cache = eth_header_cache, .cache_update = eth_header_cache_update, diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index a81dae8..492e580 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -845,7 +845,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, ph.raw = frame; - skb->protocol = proto; skb->dev = dev; skb->priority = po->sk.sk_priority; skb->mark = po->sk.sk_mark; @@ -924,6 +923,14 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, len = ((to_write > len_max) ? len_max : to_write); } + if (proto == htons(ETH_P_ALL) && dev->header_ops->get_protocol) { + skb->protocol = dev->header_ops->get_protocol(dev, skb); + if (unlikely(skb->protocol == htons(ETH_P_ALL))) + return -EINVAL; + } else { + skb->protocol = proto; + } + return tp_len; } @@ -1113,7 +1120,13 @@ static int packet_snd(struct socket *sock, if (err) goto out_free; - skb->protocol = proto; + if (proto == htons(ETH_P_ALL) && dev->header_ops->get_protocol) { + skb->protocol = dev->header_ops->get_protocol(dev, skb); + if (unlikely(skb->protocol == htons(ETH_P_ALL))) + return -EINVAL; + } else { + skb->protocol = proto; + } skb->dev = dev; skb->priority = sk->sk_priority; skb->mark = sk->sk_mark; -- MST ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH] net: packet: option to only pass skb protocol 2010-01-06 9:12 ` Michael S. Tsirkin @ 2010-01-06 19:24 ` Michael S. Tsirkin 2010-01-07 8:27 ` Michał Mirosław 1 sibling, 0 replies; 15+ messages in thread From: Michael S. Tsirkin @ 2010-01-06 19:24 UTC (permalink / raw) To: David Miller; +Cc: cfriesen, eric.dumazet, nhorman, linux-kernel, netdev On Wed, Jan 06, 2010 at 11:12:57AM +0200, Michael S. Tsirkin wrote: > On Tue, Jan 05, 2010 at 03:51:50PM -0800, David Miller wrote: > > From: "Chris Friesen" <cfriesen@nortel.com> > > Date: Tue, 05 Jan 2010 16:13:29 -0600 > > > > > If SOCK_RAW packets are being sent, the protocol number is embedded in > > > the packet data > > > > Where exactly is that protocol value? Not every link level protocol > > is ethernet. > > > > We support FDDI, HIPPI, wireless, VLAN, PPP, and a host of others. > > > > So you can't know for sure unless you assume ethernet, which you > > can't do. > > You are right. This is TX though so the socket is bound to a specific > device, and devices know which link protocol they use. So we could add a > get_protocol operation to each device type, and call it if the protocol > passed is ETH_P_ALL to get the real one. > > Like this: except I only added this for ethernet, and I would have to > add this for the rest of device types. But I would like to hear what > others think about this before I do the rest of the work for the rest of > device types. > > Does the below look sane? I mean, besides the missing semicolons etc :) Also, maybe it's a good idea to add a socket option that would trigger this behaviour, just to make sure existing behavior stays unchanged even if it's broken? > diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h > index a3fccc8..99d7801 100644 > --- a/include/linux/netdevice.h > +++ b/include/linux/netdevice.h > @@ -319,6 +319,7 @@ struct header_ops { > void (*cache_update)(struct hh_cache *hh, > const struct net_device *dev, > const unsigned char *haddr); > + __be16 (*get_protocol)(struct sk_buff *skb, struct net_device *dev) > }; > > /* These flag bits are private to the generic network queueing > diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c > index 205a1c1..3e7761d 100644 > --- a/net/ethernet/eth.c > +++ b/net/ethernet/eth.c > @@ -231,6 +231,17 @@ int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr) > EXPORT_SYMBOL(eth_header_parse); > > /** > + * eth_get_protocol - extract protocol value from packet > + * @skb: packet to extract protocol from > + * @dev: source device > + */ > +__be16 eth_get_protocol(const struct sk_buff *skb, struct net_device *dev) > +{ > + const struct ethhdr *eth = eth_hdr(skb); > + return eth->h_proto > +} > + > +/** > * eth_header_cache - fill cache entry from neighbour > * @neigh: source neighbour > * @hh: destination cache entry > @@ -324,6 +335,7 @@ EXPORT_SYMBOL(eth_validate_addr); > const struct header_ops eth_header_ops ____cacheline_aligned = { > .create = eth_header, > .parse = eth_header_parse, > + .get_protocol = eth_get_protocol, > .rebuild = eth_rebuild_header, > .cache = eth_header_cache, > .cache_update = eth_header_cache_update, > diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c > index a81dae8..492e580 100644 > --- a/net/packet/af_packet.c > +++ b/net/packet/af_packet.c > @@ -845,7 +845,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, > > ph.raw = frame; > > - skb->protocol = proto; > skb->dev = dev; > skb->priority = po->sk.sk_priority; > skb->mark = po->sk.sk_mark; > @@ -924,6 +923,14 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, > len = ((to_write > len_max) ? len_max : to_write); > } > > + if (proto == htons(ETH_P_ALL) && dev->header_ops->get_protocol) { > + skb->protocol = dev->header_ops->get_protocol(dev, skb); > + if (unlikely(skb->protocol == htons(ETH_P_ALL))) > + return -EINVAL; > + } else { > + skb->protocol = proto; > + } > + > return tp_len; > } > > @@ -1113,7 +1120,13 @@ static int packet_snd(struct socket *sock, > if (err) > goto out_free; > > - skb->protocol = proto; > + if (proto == htons(ETH_P_ALL) && dev->header_ops->get_protocol) { > + skb->protocol = dev->header_ops->get_protocol(dev, skb); > + if (unlikely(skb->protocol == htons(ETH_P_ALL))) > + return -EINVAL; > + } else { > + skb->protocol = proto; > + } > skb->dev = dev; > skb->priority = sk->sk_priority; > skb->mark = sk->sk_mark; > > -- > MST ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH] net: packet: option to only pass skb protocol 2010-01-06 9:12 ` Michael S. Tsirkin 2010-01-06 19:24 ` Michael S. Tsirkin @ 2010-01-07 8:27 ` Michał Mirosław 1 sibling, 0 replies; 15+ messages in thread From: Michał Mirosław @ 2010-01-07 8:27 UTC (permalink / raw) To: Michael S. Tsirkin Cc: David Miller, cfriesen, eric.dumazet, nhorman, linux-kernel, netdev 2010/1/6 Michael S. Tsirkin <mst@redhat.com>: > On Tue, Jan 05, 2010 at 03:51:50PM -0800, David Miller wrote: >> From: "Chris Friesen" <cfriesen@nortel.com> >> Date: Tue, 05 Jan 2010 16:13:29 -0600 >> > If SOCK_RAW packets are being sent, the protocol number is embedded in >> > the packet data >> Where exactly is that protocol value? Not every link level protocol >> is ethernet. >> We support FDDI, HIPPI, wireless, VLAN, PPP, and a host of others. >> So you can't know for sure unless you assume ethernet, which you >> can't do. > You are right. This is TX though so the socket is bound to a specific > device, and devices know which link protocol they use. So we could add a > get_protocol operation to each device type, and call it if the protocol > passed is ETH_P_ALL to get the real one. > > Like this: except I only added this for ethernet, and I would have to > add this for the rest of device types. But I would like to hear what > others think about this before I do the rest of the work for the rest of > device types. > > Does the below look sane? > [...] > diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c > index 205a1c1..3e7761d 100644 > --- a/net/ethernet/eth.c > +++ b/net/ethernet/eth.c > @@ -231,6 +231,17 @@ int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr) > EXPORT_SYMBOL(eth_header_parse); > > /** > + * eth_get_protocol - extract protocol value from packet > + * @skb: packet to extract protocol from > + * @dev: source device > + */ > +__be16 eth_get_protocol(const struct sk_buff *skb, struct net_device *dev) > +{ > + const struct ethhdr *eth = eth_hdr(skb); > + return eth->h_proto > +} [...] You might want taking fragment of eth_type_trans() for this function so that 802.2/IPX would be detected too. Best Regards, Michał Mirosław ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2010-01-07 8:27 UTC | newest] Thread overview: 15+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-01-05 18:57 [PATCH] net: packet: option to only pass skb protocol Michael S. Tsirkin 2010-01-05 19:27 ` Eric Dumazet 2010-01-05 20:50 ` Michael S. Tsirkin 2010-01-05 21:40 ` David Miller 2010-01-05 21:50 ` Michael S. Tsirkin 2010-01-05 21:28 ` Chris Friesen 2010-01-05 21:42 ` David Miller 2010-01-05 21:45 ` Michael S. Tsirkin 2010-01-05 22:05 ` Michael S. Tsirkin 2010-01-05 22:13 ` Chris Friesen 2010-01-05 22:27 ` Michael S. Tsirkin 2010-01-05 23:51 ` David Miller 2010-01-06 9:12 ` Michael S. Tsirkin 2010-01-06 19:24 ` Michael S. Tsirkin 2010-01-07 8:27 ` Michał Mirosław
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).