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 ---