ip_gre: sendto/recvfrom NBMA address
Subsystems (3)
PATCH RESEND 1/1 ip_gre: sendto/recvfrom NBMA address
When GRE tunnel is in NBMA mode, this patch allows an application to use a PF_PACKET socket to:
- send a packet to specific NBMA address with sendto()
- use recvfrom() to receive packet and check which NBMA address it came from
---
This is useful for implementing NHRP (and other low level protocols) over NBMA GRE tunnels.
Posted about a week ago, but got no reply. Could someone comment on this? Or commit it? Thanks.
net/ipv4/ip_gre.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
net/ipv4/ip_gre.c +0 -0
@@ -1033,7 +1033,6 @@ static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu)
return 0; }
-#ifdef CONFIG_NET_IPGRE_BROADCAST
/* Nice toy. Unfortunately, useless in real life :-)
It allows to construct virtual multiprotocol broadcast "LAN"
over the Internet, provided multicast routing is tuned.
@@ -1092,10 +1091,19 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
return -t->hlen; }
+static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr) +{
+ struct iphdr *iph = (struct iphdr *) skb_mac_header(skb);
+ memcpy(haddr, &iph->saddr, 4);
+ return 4;
+}
+
static const struct header_ops ipgre_header_ops = {
.create = ipgre_header,
+ .parse = ipgre_header_parse,
};
+#ifdef CONFIG_NET_IPGRE_BROADCAST
static int ipgre_open(struct net_device *dev)
{
struct ip_tunnel *t = netdev_priv(dev);
@@ -1197,6 +1205,8 @@ static int ipgre_tunnel_init(struct net_device *dev)
dev->stop = ipgre_close;
}
#endif
+ } else {
+ dev->header_ops = &ipgre_header_ops;
}
if (!tdev && tunnel->parms.link)Quoted 8 lines · Timo Teräs
When GRE tunnel is in NBMA mode, this patch allows an application to use a
PF_PACKETsocket to:
- send a packet to specific NBMA address withsendto()
- userecvfrom()to receive packet and check which NBMA address it came fromSigned-off-by Timo Teras <[email protected]>
Quoted 7 lines
---
This is useful for implementing NHRP (and other low level protocols) over NBMA GRE tunnels.
Posted about a week ago, but got no reply. Could someone comment on this? Or commit it? Thanks.
Your mailer mangled tabs, it won't apply like this. Try sending to yourself for testing, then repost when it works properly.
PATCH RESEND 1/1 ip_gre: sendto/recvfrom NBMA address
When GRE tunnel is in NBMA mode, this patch allows an application to use a PF_PACKET socket to:
- send a packet to specific NBMA address with sendto()
- use recvfrom() to receive packet and check which NBMA address it came from
This is required to implement properly NHRP over GRE tunnel.
---
Quoted 2 lines
Your mailer mangled tabs, it won't apply like this. Try sending to yourself for testing, then repost when it works properly.
Sorry. Tabs were ok, but the initial white space on context lines was somehow removed. Apparently a bug in my editor where I cut/pasted from.
net/ipv4/ip_gre.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
net/ipv4/ip_gre.c +0 -0
@@ -1033,7 +1033,6 @@ static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu)
return 0; }
-#ifdef CONFIG_NET_IPGRE_BROADCAST
/* Nice toy. Unfortunately, useless in real life :-)
It allows to construct virtual multiprotocol broadcast "LAN"
over the Internet, provided multicast routing is tuned.
@@ -1092,10 +1091,19 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
return -t->hlen; }
+static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr) +{
+ struct iphdr *iph = (struct iphdr*) skb_mac_header(skb);
+ memcpy(haddr, &iph->saddr, 4);
+ return 4;
+}
+
static const struct header_ops ipgre_header_ops = {
.create = ipgre_header,
+ .parse = ipgre_header_parse,
};
+#ifdef CONFIG_NET_IPGRE_BROADCAST
static int ipgre_open(struct net_device *dev)
{
struct ip_tunnel *t = netdev_priv(dev);
@@ -1197,6 +1205,8 @@ static int ipgre_tunnel_init(struct net_device *dev)
dev->stop = ipgre_close;
}
#endif
+ } else {
+ dev->header_ops = &ipgre_header_ops;
}
if (!tdev && tunnel->parms.link)PATCH RESEND 1/1 ip_gre: sendto/recvfrom NBMA address
In reply to Patrick McHardyWhen GRE tunnel is in NBMA mode, this patch allows an application to use a PF_PACKET socket to:
- send a packet to specific NBMA address with sendto()
- use recvfrom() to receive packet and check which NBMA address it came from
This is required to implement properly NHRP over GRE tunnel.
---
Quoted 2 lines · Patrick McHardy
Your mailer mangled tabs, it won't apply like this. Try sending to yourself for testing, then repost when it works properly.
Tabs were ok, I think. But somehow it seems that cut'n'paste from my default editor loses the space from context lines. It should be good now.
net/ipv4/ip_gre.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
net/ipv4/ip_gre.c +0 -0
@@ -1033,7 +1033,6 @@ static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu)
return 0; }
-#ifdef CONFIG_NET_IPGRE_BROADCAST
/* Nice toy. Unfortunately, useless in real life :-)
It allows to construct virtual multiprotocol broadcast "LAN"
over the Internet, provided multicast routing is tuned.
@@ -1092,10 +1091,19 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
return -t->hlen; }
+static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr) +{
+ struct iphdr *iph = (struct iphdr*) skb_mac_header(skb);
+ memcpy(haddr, &iph->saddr, 4);
+ return 4;
+}
+
static const struct header_ops ipgre_header_ops = {
.create = ipgre_header,
+ .parse = ipgre_header_parse,
};
+#ifdef CONFIG_NET_IPGRE_BROADCAST
static int ipgre_open(struct net_device *dev)
{
struct ip_tunnel *t = netdev_priv(dev);
@@ -1197,6 +1205,8 @@ static int ipgre_tunnel_init(struct net_device *dev)
dev->stop = ipgre_close;
}
#endif
+ } else {
+ dev->header_ops = &ipgre_header_ops;
}
if (!tdev && tunnel->parms.link)Quoted 10 lines · Timo Teräs
When GRE tunnel is in NBMA mode, this patch allows an application to use a
PF_PACKETsocket to:
- send a packet to specific NBMA address withsendto()
- userecvfrom()to receive packet and check which NBMA address it came fromThis is required to implement properly NHRP over GRE tunnel.
Signed-off-by Timo Teras <[email protected]>
Quoted 7 lines
---
Quoted 2 lines · Patrick McHardy
Your mailer mangled tabs, it won't apply like this. Try sending to yourself for testing, then repost when it works properly.
Tabs were ok, I think. But somehow it seems that cut'n'paste from my default editor loses the space from context lines. It should be good now.
Might have been a problem on my side, I just updated my mailer and it still displays tabs broken, but the actual patch seems fine. Sorry for the noise ...
Hello!
Quoted 6 lines
When GRE tunnel is in NBMA mode, this patch allows an application to use a
PF_PACKETsocket to:
- send a packet to specific NBMA address withsendto()
- userecvfrom()to receive packet and check which NBMA address it came fromThis is required to implement properly NHRP over GRE tunnel.
Ack. This is good idea.
Frankly, I was sure ip_gre worked in this way all these years. I do not remember any reasons why it was crippled.
The only dubious case is when next hop is set using routing tables. But code in ipgre_tunnel_xmit() is ready to accept this situation, it checks for zero destination address and fixes it when it is able to.
Alexey
David Miller
maintainerFrom: Alexey Kuznetsov <[email protected]>
Date: Tue, 23 Oct 2007 23:03:24 +0400
Quoted 10 lines
Hello!
Quoted 6 lines
When GRE tunnel is in NBMA mode, this patch allows an application to use a
PF_PACKETsocket to:
- send a packet to specific NBMA address withsendto()
- userecvfrom()to receive packet and check which NBMA address it came fromThis is required to implement properly NHRP over GRE tunnel.
Ack. This is good idea.
Patch applied, thanks everyone!
Hello!
Quoted 8 lines · Me
Ack. This is good idea.
Frankly, I was sure
ip_greworked in this way all these years. I do not remember any reasons why it was crippled.The only dubious case is when next hop is set using routing tables. But code in
ipgre_tunnel_xmit()is ready to accept this situation, it checks for zero destination address and fixes it when it is able to.
Nevertheless, it does not work.
The reason is that NOARP arp entries on device with initialized hard_header are initialized not to all zeros, but to dev->dev_addr. So that, netxthop from routing tables is ignored and all gre packets are lost in loopback. Not good.
The problem can be ignored. I am even not sure that someone uses this feature. Actually, it was not recommended in documentation.
Alternatively, arp.c can be changed to generate 0 addresses instead of dev->dev_addr. Normally it is equally good, but I am not sure about possible side effects.
Another thoughts?
Alexey
Hi,
Quoted 7 lines · Alexey Kuznetsov
Quoted 3 lines
The only dubious case is when next hop is set using routing tables. But code in
ipgre_tunnel_xmit()is ready to accept this situation, it checks for zero destination address and fixes it when it is able to.Nevertheless, it does not work.
Another thoughts?
Could you explain this a little more?
I was able to set a nbma gre tunnel, add routes to it and it worked perfectly ok.
Link-level next hop worked:
ip route add <route> via <link-level-address> dev <tunnel-dev> onlink
Also normal route with static neighbor worked:
ip neigh add <router-tunnel-ip> lladdr <link-level-address> nud permanent dev <tunnel-dev> ip route add <route> via <router-tunnel-ip>
In both cases packets were routed as expected to hosts accessible using the added route. And sendto() sent a packet correctly with destination link-level-address set. Did I miss/misunderstand something?
Cheers,
Timo
Hello!
Quoted 5 lines
I was able to set a nbma gre tunnel, add routes to it and it worked perfectly ok.
Link-level next hop worked:
ip route add <route> via <link-level-address> dev <tunnel-dev> onlink
This can work if you use gre0. By plain luck it has all-zero dev_addr.
It will break on nbma devices set with:
ip tunnel add XXX mode gre local a.b.c.d [key whatever] ...
Alexey
RFC PATCH 1/1 ip_gre: use skb->{mac,network}_header consistently
From: Timo Teras <[email protected]>
Make both send and receive paths use consistently skb->*_header:
mac_header = outer IPv4 header
network_header = encapsulated packet (e.g. inner IPv4 header)
---
Currently in send path:
network_header = outer IPv4 header
transport_header = encapsulated packet
And receive path:
network_header = encapsulated packet
mac_header = GRE header
mac_header used to be the outer IPv4 header on receive path, but it was broken/changed when skb_reset_mac_header() was introduced.
This also makes ipgre_header_parse() work correctly as it assumes that mac_header points to the outer IPv4 header always. Though, it returns zeros for outgoing packets that are tcpdumped from gre tunnel without explicit local address, since the routing is done in ipgre_tunnel_xmit().
net/ipv4/ip_gre.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
net/ipv4/ip_gre.c +4 -4
@@ -613,7 +613,7 @@ static int ipgre_rcv(struct sk_buff *skb) offset +=4 ; } -skb_reset_mac_header (skb); + skb->mac_header = skb->network_header;__pskb_pull (skb, offset);skb_reset_network_header (skb);skb_postpull_rcsum (skb,skb_transport_header (skb), offset);
@@ -826,9 +826,8 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) old_iph =ip_hdr (skb); } - skb->transport_header = skb->network_header;skb_push (skb, gre_hlen); -skb_reset_network_header (skb); +skb_reset_mac_header (skb);memset (&(IPCB (skb)->opt),0 ,sizeof (IPCB (skb)->opt));IPCB (skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE |IPSKB_XFRM_TRANSFORMED |IPSKB_REROUTED );
@@ -839,7 +838,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)* Push down and install the IPIP header. */ - iph =ip_hdr (skb); + iph = (struct iphdr *)skb_mac_header (skb); iph->version =4 ; iph->ihl =sizeof (struct iphdr ) >>2 ; iph->frag_off = df;
@@ -1070,6 +1069,7 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev,struct iphdr *iph = (struct iphdr *)skb_push (skb, t->hlen);__be16 *p = (__be16 *)(iph+1 ); +skb_reset_mac_header (skb);memcpy (iph, &t->parms.iph,sizeof (struct iphdr )); p[0 ] = t->parms.o_flags; p[1 ] =htons (type);
Signature · 1 line
1.5.2.5
PATCH 1/1 ip_gre: set mac_header correctly in receive path
From: Timo Teras <[email protected]>
mac_header update in ipgre_recv() was incorrectly changed to skb_reset_mac_header() when it was introduced.
---
This replaces my earlier patch titled "ip_gre: use skb->{mac, network}_header consistently". Apparently I hadn't done my homework how to use *_header correctly. And I should have done a bit more testing to figure out the previous patch does not work.
But the main problem was the receive path in the first place, and this patch fixes it.
The bug was introduced in commit 459a98ed881802dee55897441bc7f77af614368e. There might be other similar incorrect replaces.
net/ipv4/ip_gre.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
net/ipv4/ip_gre.c +1 -1
@@ -613,7 +613,7 @@ static int ipgre_rcv(struct sk_buff *skb) offset +=4 ; } -skb_reset_mac_header (skb); + skb->mac_header = skb->network_header;__pskb_pull (skb, offset);skb_reset_network_header (skb);skb_postpull_rcsum (skb,skb_transport_header (skb), offset);
Signature · 1 line
1.5.2.5
David Miller
maintainerRe: [PATCH][IPV4] ip_gre: set mac_header correctly in receive path
From: Timo_Teräs <[email protected]>
Date: Wed, 19 Dec 2007 20:10:41 +0200
Quoted 6 lines
From: Timo Teras <[email protected]>
mac_headerupdate inipgre_recv()was incorrectly changed toskb_reset_mac_header()when it was introduced.Signed-off-by Timo Teras <[email protected]>
Patch applied, thanks.
Quoted 11 lines
---
This replaces my earlier patch titled "ip_gre: use skb->{mac, network}_header consistently". Apparently I hadn't done my homework how to use*_headercorrectly. And I should have done a bit more testing to figure out the previous patch does not work.But the main problem was the receive path in the first place, and this patch fixes it.
The bug was introduced in commit
459a98ed881802dee55897441bc7f77af614368e. There might be other similar incorrect replaces.
That commit has two other identical bad conversions, I'll fix them up.