aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorPravin B Shelar <pshelar@nicira.com>2015-10-22 21:17:16 -0400
committerDavid S. Miller <davem@davemloft.net>2015-10-22 22:39:25 -0400
commitfc4099f17240767554ff3a73977acb78ef615404 (patch)
tree3a4cfa8db0ec0fa58c15af23b6745dc01b8f8e38 /net/ipv4
parent0c472b9b391ecf9011d383956b322e72593d87b2 (diff)
openvswitch: Fix egress tunnel info.
While transitioning to netdev based vport we broke OVS feature which allows user to retrieve tunnel packet egress information for lwtunnel devices. Following patch fixes it by introducing ndo operation to get the tunnel egress info. Same ndo operation can be used for lwtunnel devices and compat ovs-tnl-vport devices. So after adding such device operation we can remove similar operation from ovs-vport. Fixes: 614732eaa12d ("openvswitch: Use regular VXLAN net_device device"). Signed-off-by: Pravin B Shelar <pshelar@nicira.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ip_gre.c46
1 files changed, 37 insertions, 9 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index bd0679d90519..614521437e30 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -498,10 +498,26 @@ static struct sk_buff *gre_handle_offloads(struct sk_buff *skb,
498 csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE); 498 csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
499} 499}
500 500
501static struct rtable *gre_get_rt(struct sk_buff *skb,
502 struct net_device *dev,
503 struct flowi4 *fl,
504 const struct ip_tunnel_key *key)
505{
506 struct net *net = dev_net(dev);
507
508 memset(fl, 0, sizeof(*fl));
509 fl->daddr = key->u.ipv4.dst;
510 fl->saddr = key->u.ipv4.src;
511 fl->flowi4_tos = RT_TOS(key->tos);
512 fl->flowi4_mark = skb->mark;
513 fl->flowi4_proto = IPPROTO_GRE;
514
515 return ip_route_output_key(net, fl);
516}
517
501static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev) 518static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev)
502{ 519{
503 struct ip_tunnel_info *tun_info; 520 struct ip_tunnel_info *tun_info;
504 struct net *net = dev_net(dev);
505 const struct ip_tunnel_key *key; 521 const struct ip_tunnel_key *key;
506 struct flowi4 fl; 522 struct flowi4 fl;
507 struct rtable *rt; 523 struct rtable *rt;
@@ -516,14 +532,7 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev)
516 goto err_free_skb; 532 goto err_free_skb;
517 533
518 key = &tun_info->key; 534 key = &tun_info->key;
519 memset(&fl, 0, sizeof(fl)); 535 rt = gre_get_rt(skb, dev, &fl, key);
520 fl.daddr = key->u.ipv4.dst;
521 fl.saddr = key->u.ipv4.src;
522 fl.flowi4_tos = RT_TOS(key->tos);
523 fl.flowi4_mark = skb->mark;
524 fl.flowi4_proto = IPPROTO_GRE;
525
526 rt = ip_route_output_key(net, &fl);
527 if (IS_ERR(rt)) 536 if (IS_ERR(rt))
528 goto err_free_skb; 537 goto err_free_skb;
529 538
@@ -566,6 +575,24 @@ err_free_skb:
566 dev->stats.tx_dropped++; 575 dev->stats.tx_dropped++;
567} 576}
568 577
578static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
579{
580 struct ip_tunnel_info *info = skb_tunnel_info(skb);
581 struct rtable *rt;
582 struct flowi4 fl4;
583
584 if (ip_tunnel_info_af(info) != AF_INET)
585 return -EINVAL;
586
587 rt = gre_get_rt(skb, dev, &fl4, &info->key);
588 if (IS_ERR(rt))
589 return PTR_ERR(rt);
590
591 ip_rt_put(rt);
592 info->key.u.ipv4.src = fl4.saddr;
593 return 0;
594}
595
569static netdev_tx_t ipgre_xmit(struct sk_buff *skb, 596static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
570 struct net_device *dev) 597 struct net_device *dev)
571{ 598{
@@ -1023,6 +1050,7 @@ static const struct net_device_ops gre_tap_netdev_ops = {
1023 .ndo_change_mtu = ip_tunnel_change_mtu, 1050 .ndo_change_mtu = ip_tunnel_change_mtu,
1024 .ndo_get_stats64 = ip_tunnel_get_stats64, 1051 .ndo_get_stats64 = ip_tunnel_get_stats64,
1025 .ndo_get_iflink = ip_tunnel_get_iflink, 1052 .ndo_get_iflink = ip_tunnel_get_iflink,
1053 .ndo_fill_metadata_dst = gre_fill_metadata_dst,
1026}; 1054};
1027 1055
1028static void ipgre_tap_setup(struct net_device *dev) 1056static void ipgre_tap_setup(struct net_device *dev)