diff options
author | Tom Herbert <therbert@google.com> | 2014-09-17 15:26:00 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-19 17:15:32 -0400 |
commit | 473ab820dd4af588785a8e10b9c1547aadb4fd72 (patch) | |
tree | 478bb4b8987b7cd1f2ad1e0b7d5756ce6b993a94 /net/ipv4/ipip.c | |
parent | 14909664e4e192f4c6f6fcdccd9919af7cf783ab (diff) |
ipip: Setup and TX path for ipip/UDP foo-over-udp encapsulation
Add netlink handling for IP tunnel encapsulation parameters and
and adjustment of MTU for encapsulation. ip_tunnel_encap is called
from ip_tunnel_xmit to actually perform FOU encapsulation.
Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ipip.c')
-rw-r--r-- | net/ipv4/ipip.c | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 62eaa005e146..bfec31df8b21 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -301,7 +301,8 @@ static int ipip_tunnel_init(struct net_device *dev) | |||
301 | memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4); | 301 | memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4); |
302 | memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); | 302 | memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); |
303 | 303 | ||
304 | tunnel->hlen = 0; | 304 | tunnel->tun_hlen = 0; |
305 | tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen; | ||
305 | tunnel->parms.iph.protocol = IPPROTO_IPIP; | 306 | tunnel->parms.iph.protocol = IPPROTO_IPIP; |
306 | return ip_tunnel_init(dev); | 307 | return ip_tunnel_init(dev); |
307 | } | 308 | } |
@@ -340,10 +341,53 @@ static void ipip_netlink_parms(struct nlattr *data[], | |||
340 | parms->iph.frag_off = htons(IP_DF); | 341 | parms->iph.frag_off = htons(IP_DF); |
341 | } | 342 | } |
342 | 343 | ||
344 | /* This function returns true when ENCAP attributes are present in the nl msg */ | ||
345 | static bool ipip_netlink_encap_parms(struct nlattr *data[], | ||
346 | struct ip_tunnel_encap *ipencap) | ||
347 | { | ||
348 | bool ret = false; | ||
349 | |||
350 | memset(ipencap, 0, sizeof(*ipencap)); | ||
351 | |||
352 | if (!data) | ||
353 | return ret; | ||
354 | |||
355 | if (data[IFLA_IPTUN_ENCAP_TYPE]) { | ||
356 | ret = true; | ||
357 | ipencap->type = nla_get_u16(data[IFLA_IPTUN_ENCAP_TYPE]); | ||
358 | } | ||
359 | |||
360 | if (data[IFLA_IPTUN_ENCAP_FLAGS]) { | ||
361 | ret = true; | ||
362 | ipencap->flags = nla_get_u16(data[IFLA_IPTUN_ENCAP_FLAGS]); | ||
363 | } | ||
364 | |||
365 | if (data[IFLA_IPTUN_ENCAP_SPORT]) { | ||
366 | ret = true; | ||
367 | ipencap->sport = nla_get_u16(data[IFLA_IPTUN_ENCAP_SPORT]); | ||
368 | } | ||
369 | |||
370 | if (data[IFLA_IPTUN_ENCAP_DPORT]) { | ||
371 | ret = true; | ||
372 | ipencap->dport = nla_get_u16(data[IFLA_IPTUN_ENCAP_DPORT]); | ||
373 | } | ||
374 | |||
375 | return ret; | ||
376 | } | ||
377 | |||
343 | static int ipip_newlink(struct net *src_net, struct net_device *dev, | 378 | static int ipip_newlink(struct net *src_net, struct net_device *dev, |
344 | struct nlattr *tb[], struct nlattr *data[]) | 379 | struct nlattr *tb[], struct nlattr *data[]) |
345 | { | 380 | { |
346 | struct ip_tunnel_parm p; | 381 | struct ip_tunnel_parm p; |
382 | struct ip_tunnel_encap ipencap; | ||
383 | |||
384 | if (ipip_netlink_encap_parms(data, &ipencap)) { | ||
385 | struct ip_tunnel *t = netdev_priv(dev); | ||
386 | int err = ip_tunnel_encap_setup(t, &ipencap); | ||
387 | |||
388 | if (err < 0) | ||
389 | return err; | ||
390 | } | ||
347 | 391 | ||
348 | ipip_netlink_parms(data, &p); | 392 | ipip_netlink_parms(data, &p); |
349 | return ip_tunnel_newlink(dev, tb, &p); | 393 | return ip_tunnel_newlink(dev, tb, &p); |
@@ -353,6 +397,15 @@ static int ipip_changelink(struct net_device *dev, struct nlattr *tb[], | |||
353 | struct nlattr *data[]) | 397 | struct nlattr *data[]) |
354 | { | 398 | { |
355 | struct ip_tunnel_parm p; | 399 | struct ip_tunnel_parm p; |
400 | struct ip_tunnel_encap ipencap; | ||
401 | |||
402 | if (ipip_netlink_encap_parms(data, &ipencap)) { | ||
403 | struct ip_tunnel *t = netdev_priv(dev); | ||
404 | int err = ip_tunnel_encap_setup(t, &ipencap); | ||
405 | |||
406 | if (err < 0) | ||
407 | return err; | ||
408 | } | ||
356 | 409 | ||
357 | ipip_netlink_parms(data, &p); | 410 | ipip_netlink_parms(data, &p); |
358 | 411 | ||
@@ -378,6 +431,14 @@ static size_t ipip_get_size(const struct net_device *dev) | |||
378 | nla_total_size(1) + | 431 | nla_total_size(1) + |
379 | /* IFLA_IPTUN_PMTUDISC */ | 432 | /* IFLA_IPTUN_PMTUDISC */ |
380 | nla_total_size(1) + | 433 | nla_total_size(1) + |
434 | /* IFLA_IPTUN_ENCAP_TYPE */ | ||
435 | nla_total_size(2) + | ||
436 | /* IFLA_IPTUN_ENCAP_FLAGS */ | ||
437 | nla_total_size(2) + | ||
438 | /* IFLA_IPTUN_ENCAP_SPORT */ | ||
439 | nla_total_size(2) + | ||
440 | /* IFLA_IPTUN_ENCAP_DPORT */ | ||
441 | nla_total_size(2) + | ||
381 | 0; | 442 | 0; |
382 | } | 443 | } |
383 | 444 | ||
@@ -394,6 +455,17 @@ static int ipip_fill_info(struct sk_buff *skb, const struct net_device *dev) | |||
394 | nla_put_u8(skb, IFLA_IPTUN_PMTUDISC, | 455 | nla_put_u8(skb, IFLA_IPTUN_PMTUDISC, |
395 | !!(parm->iph.frag_off & htons(IP_DF)))) | 456 | !!(parm->iph.frag_off & htons(IP_DF)))) |
396 | goto nla_put_failure; | 457 | goto nla_put_failure; |
458 | |||
459 | if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, | ||
460 | tunnel->encap.type) || | ||
461 | nla_put_u16(skb, IFLA_IPTUN_ENCAP_SPORT, | ||
462 | tunnel->encap.sport) || | ||
463 | nla_put_u16(skb, IFLA_IPTUN_ENCAP_DPORT, | ||
464 | tunnel->encap.dport) || | ||
465 | nla_put_u16(skb, IFLA_IPTUN_ENCAP_FLAGS, | ||
466 | tunnel->encap.dport)) | ||
467 | goto nla_put_failure; | ||
468 | |||
397 | return 0; | 469 | return 0; |
398 | 470 | ||
399 | nla_put_failure: | 471 | nla_put_failure: |
@@ -407,6 +479,10 @@ static const struct nla_policy ipip_policy[IFLA_IPTUN_MAX + 1] = { | |||
407 | [IFLA_IPTUN_TTL] = { .type = NLA_U8 }, | 479 | [IFLA_IPTUN_TTL] = { .type = NLA_U8 }, |
408 | [IFLA_IPTUN_TOS] = { .type = NLA_U8 }, | 480 | [IFLA_IPTUN_TOS] = { .type = NLA_U8 }, |
409 | [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 }, | 481 | [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 }, |
482 | [IFLA_IPTUN_ENCAP_TYPE] = { .type = NLA_U16 }, | ||
483 | [IFLA_IPTUN_ENCAP_FLAGS] = { .type = NLA_U16 }, | ||
484 | [IFLA_IPTUN_ENCAP_SPORT] = { .type = NLA_U16 }, | ||
485 | [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 }, | ||
410 | }; | 486 | }; |
411 | 487 | ||
412 | static struct rtnl_link_ops ipip_link_ops __read_mostly = { | 488 | static struct rtnl_link_ops ipip_link_ops __read_mostly = { |