vrf.c (bba73071b6f71be0a101658d7c13866e30b264a6) | vrf.c (b75cc8f90f07342467b3bd51dbc0054f185032c9) |
---|---|
1/* 2 * vrf.c: device driver to encapsulate a VRF space 3 * 4 * Copyright (c) 2015 Cumulus Networks. All rights reserved. 5 * Copyright (c) 2015 Shrijeet Mukherjee <shm@cumulusnetworks.com> 6 * Copyright (c) 2015 David Ahern <dsa@cumulusnetworks.com> 7 * 8 * Based on dummy, team and ipvlan drivers --- 722 unchanged lines hidden (view full) --- 731 return -ENOMEM; 732 733 /* create a dst for routing packets out through a VRF device */ 734 rth = rt_dst_alloc(dev, 0, RTN_UNICAST, 1, 1, 0); 735 if (!rth) 736 return -ENOMEM; 737 738 rth->dst.output = vrf_output; | 1/* 2 * vrf.c: device driver to encapsulate a VRF space 3 * 4 * Copyright (c) 2015 Cumulus Networks. All rights reserved. 5 * Copyright (c) 2015 Shrijeet Mukherjee <shm@cumulusnetworks.com> 6 * Copyright (c) 2015 David Ahern <dsa@cumulusnetworks.com> 7 * 8 * Based on dummy, team and ipvlan drivers --- 722 unchanged lines hidden (view full) --- 731 return -ENOMEM; 732 733 /* create a dst for routing packets out through a VRF device */ 734 rth = rt_dst_alloc(dev, 0, RTN_UNICAST, 1, 1, 0); 735 if (!rth) 736 return -ENOMEM; 737 738 rth->dst.output = vrf_output; |
739 rth->rt_table_id = vrf->tb_id; | |
740 741 rcu_assign_pointer(vrf->rth, rth); 742 743 return 0; 744} 745 746/**************************** device handling ********************/ 747 --- 189 unchanged lines hidden (view full) --- 937out: 938 return rc; 939} 940 941static struct rt6_info *vrf_ip6_route_lookup(struct net *net, 942 const struct net_device *dev, 943 struct flowi6 *fl6, 944 int ifindex, | 739 740 rcu_assign_pointer(vrf->rth, rth); 741 742 return 0; 743} 744 745/**************************** device handling ********************/ 746 --- 189 unchanged lines hidden (view full) --- 936out: 937 return rc; 938} 939 940static struct rt6_info *vrf_ip6_route_lookup(struct net *net, 941 const struct net_device *dev, 942 struct flowi6 *fl6, 943 int ifindex, |
944 const struct sk_buff *skb, |
|
945 int flags) 946{ 947 struct net_vrf *vrf = netdev_priv(dev); 948 struct fib6_table *table = NULL; 949 struct rt6_info *rt6; 950 951 rcu_read_lock(); 952 953 /* fib6_table does not have a refcnt and can not be freed */ 954 rt6 = rcu_dereference(vrf->rt6); 955 if (likely(rt6)) 956 table = rt6->rt6i_table; 957 958 rcu_read_unlock(); 959 960 if (!table) 961 return NULL; 962 | 945 int flags) 946{ 947 struct net_vrf *vrf = netdev_priv(dev); 948 struct fib6_table *table = NULL; 949 struct rt6_info *rt6; 950 951 rcu_read_lock(); 952 953 /* fib6_table does not have a refcnt and can not be freed */ 954 rt6 = rcu_dereference(vrf->rt6); 955 if (likely(rt6)) 956 table = rt6->rt6i_table; 957 958 rcu_read_unlock(); 959 960 if (!table) 961 return NULL; 962 |
963 return ip6_pol_route(net, table, ifindex, fl6, flags); | 963 return ip6_pol_route(net, table, ifindex, fl6, skb, flags); |
964} 965 966static void vrf_ip6_input_dst(struct sk_buff *skb, struct net_device *vrf_dev, 967 int ifindex) 968{ 969 const struct ipv6hdr *iph = ipv6_hdr(skb); 970 struct flowi6 fl6 = { 971 .flowi6_iif = ifindex, 972 .flowi6_mark = skb->mark, 973 .flowi6_proto = iph->nexthdr, 974 .daddr = iph->daddr, 975 .saddr = iph->saddr, 976 .flowlabel = ip6_flowinfo(iph), 977 }; 978 struct net *net = dev_net(vrf_dev); 979 struct rt6_info *rt6; 980 | 964} 965 966static void vrf_ip6_input_dst(struct sk_buff *skb, struct net_device *vrf_dev, 967 int ifindex) 968{ 969 const struct ipv6hdr *iph = ipv6_hdr(skb); 970 struct flowi6 fl6 = { 971 .flowi6_iif = ifindex, 972 .flowi6_mark = skb->mark, 973 .flowi6_proto = iph->nexthdr, 974 .daddr = iph->daddr, 975 .saddr = iph->saddr, 976 .flowlabel = ip6_flowinfo(iph), 977 }; 978 struct net *net = dev_net(vrf_dev); 979 struct rt6_info *rt6; 980 |
981 rt6 = vrf_ip6_route_lookup(net, vrf_dev, &fl6, ifindex, | 981 rt6 = vrf_ip6_route_lookup(net, vrf_dev, &fl6, ifindex, skb, |
982 RT6_LOOKUP_F_HAS_SADDR | RT6_LOOKUP_F_IFACE); 983 if (unlikely(!rt6)) 984 return; 985 986 if (unlikely(&rt6->dst == &net->ipv6.ip6_null_entry->dst)) 987 return; 988 989 skb_dst_set(skb, &rt6->dst); --- 116 unchanged lines hidden (view full) --- 1106 dst = &net->ipv6.ip6_null_entry->dst; 1107 dst_hold(dst); 1108 return dst; 1109 } 1110 1111 if (!ipv6_addr_any(&fl6->saddr)) 1112 flags |= RT6_LOOKUP_F_HAS_SADDR; 1113 | 982 RT6_LOOKUP_F_HAS_SADDR | RT6_LOOKUP_F_IFACE); 983 if (unlikely(!rt6)) 984 return; 985 986 if (unlikely(&rt6->dst == &net->ipv6.ip6_null_entry->dst)) 987 return; 988 989 skb_dst_set(skb, &rt6->dst); --- 116 unchanged lines hidden (view full) --- 1106 dst = &net->ipv6.ip6_null_entry->dst; 1107 dst_hold(dst); 1108 return dst; 1109 } 1110 1111 if (!ipv6_addr_any(&fl6->saddr)) 1112 flags |= RT6_LOOKUP_F_HAS_SADDR; 1113 |
1114 rt = vrf_ip6_route_lookup(net, dev, fl6, fl6->flowi6_oif, flags); | 1114 rt = vrf_ip6_route_lookup(net, dev, fl6, fl6->flowi6_oif, NULL, flags); |
1115 if (rt) 1116 dst = &rt->dst; 1117 1118 return dst; 1119} 1120#endif 1121 1122static const struct l3mdev_ops vrf_l3mdev_ops = { --- 18 unchanged lines hidden (view full) --- 1141 1142static inline size_t vrf_fib_rule_nl_size(void) 1143{ 1144 size_t sz; 1145 1146 sz = NLMSG_ALIGN(sizeof(struct fib_rule_hdr)); 1147 sz += nla_total_size(sizeof(u8)); /* FRA_L3MDEV */ 1148 sz += nla_total_size(sizeof(u32)); /* FRA_PRIORITY */ | 1115 if (rt) 1116 dst = &rt->dst; 1117 1118 return dst; 1119} 1120#endif 1121 1122static const struct l3mdev_ops vrf_l3mdev_ops = { --- 18 unchanged lines hidden (view full) --- 1141 1142static inline size_t vrf_fib_rule_nl_size(void) 1143{ 1144 size_t sz; 1145 1146 sz = NLMSG_ALIGN(sizeof(struct fib_rule_hdr)); 1147 sz += nla_total_size(sizeof(u8)); /* FRA_L3MDEV */ 1148 sz += nla_total_size(sizeof(u32)); /* FRA_PRIORITY */ |
1149 sz += nla_total_size(sizeof(u8)); /* FRA_PROTOCOL */ |
|
1149 1150 return sz; 1151} 1152 1153static int vrf_fib_rule(const struct net_device *dev, __u8 family, bool add_it) 1154{ 1155 struct fib_rule_hdr *frh; 1156 struct nlmsghdr *nlh; --- 14 unchanged lines hidden (view full) --- 1171 /* rule only needs to appear once */ 1172 nlh->nlmsg_flags |= NLM_F_EXCL; 1173 1174 frh = nlmsg_data(nlh); 1175 memset(frh, 0, sizeof(*frh)); 1176 frh->family = family; 1177 frh->action = FR_ACT_TO_TBL; 1178 | 1150 1151 return sz; 1152} 1153 1154static int vrf_fib_rule(const struct net_device *dev, __u8 family, bool add_it) 1155{ 1156 struct fib_rule_hdr *frh; 1157 struct nlmsghdr *nlh; --- 14 unchanged lines hidden (view full) --- 1172 /* rule only needs to appear once */ 1173 nlh->nlmsg_flags |= NLM_F_EXCL; 1174 1175 frh = nlmsg_data(nlh); 1176 memset(frh, 0, sizeof(*frh)); 1177 frh->family = family; 1178 frh->action = FR_ACT_TO_TBL; 1179 |
1180 if (nla_put_u8(skb, FRA_PROTOCOL, RTPROT_KERNEL)) 1181 goto nla_put_failure; 1182 |
|
1179 if (nla_put_u8(skb, FRA_L3MDEV, 1)) 1180 goto nla_put_failure; 1181 1182 if (nla_put_u32(skb, FRA_PRIORITY, FIB_RULE_PREF)) 1183 goto nla_put_failure; 1184 1185 nlmsg_end(skb, nlh); 1186 --- 239 unchanged lines hidden (view full) --- 1426 1427 return 0; 1428} 1429 1430static struct pernet_operations vrf_net_ops __net_initdata = { 1431 .init = vrf_netns_init, 1432 .id = &vrf_net_id, 1433 .size = sizeof(bool), | 1183 if (nla_put_u8(skb, FRA_L3MDEV, 1)) 1184 goto nla_put_failure; 1185 1186 if (nla_put_u32(skb, FRA_PRIORITY, FIB_RULE_PREF)) 1187 goto nla_put_failure; 1188 1189 nlmsg_end(skb, nlh); 1190 --- 239 unchanged lines hidden (view full) --- 1430 1431 return 0; 1432} 1433 1434static struct pernet_operations vrf_net_ops __net_initdata = { 1435 .init = vrf_netns_init, 1436 .id = &vrf_net_id, 1437 .size = sizeof(bool), |
1438 .async = true, |
|
1434}; 1435 1436static int __init vrf_init_module(void) 1437{ 1438 int rc; 1439 1440 register_netdevice_notifier(&vrf_notifier_block); 1441 --- 23 unchanged lines hidden --- | 1439}; 1440 1441static int __init vrf_init_module(void) 1442{ 1443 int rc; 1444 1445 register_netdevice_notifier(&vrf_notifier_block); 1446 --- 23 unchanged lines hidden --- |