aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_semantics.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/fib_semantics.c')
-rw-r--r--net/ipv4/fib_semantics.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 12d3dc3df1b7..48e93a560077 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -152,6 +152,8 @@ static void free_fib_info_rcu(struct rcu_head *head)
152{ 152{
153 struct fib_info *fi = container_of(head, struct fib_info, rcu); 153 struct fib_info *fi = container_of(head, struct fib_info, rcu);
154 154
155 if (fi->fib_metrics != (u32 *) dst_default_metrics)
156 kfree(fi->fib_metrics);
155 kfree(fi); 157 kfree(fi);
156} 158}
157 159
@@ -200,7 +202,7 @@ static inline int nh_comp(const struct fib_info *fi, const struct fib_info *ofi)
200#ifdef CONFIG_IP_ROUTE_MULTIPATH 202#ifdef CONFIG_IP_ROUTE_MULTIPATH
201 nh->nh_weight != onh->nh_weight || 203 nh->nh_weight != onh->nh_weight ||
202#endif 204#endif
203#ifdef CONFIG_NET_CLS_ROUTE 205#ifdef CONFIG_IP_ROUTE_CLASSID
204 nh->nh_tclassid != onh->nh_tclassid || 206 nh->nh_tclassid != onh->nh_tclassid ||
205#endif 207#endif
206 ((nh->nh_flags ^ onh->nh_flags) & ~RTNH_F_DEAD)) 208 ((nh->nh_flags ^ onh->nh_flags) & ~RTNH_F_DEAD))
@@ -422,7 +424,7 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
422 424
423 nla = nla_find(attrs, attrlen, RTA_GATEWAY); 425 nla = nla_find(attrs, attrlen, RTA_GATEWAY);
424 nexthop_nh->nh_gw = nla ? nla_get_be32(nla) : 0; 426 nexthop_nh->nh_gw = nla ? nla_get_be32(nla) : 0;
425#ifdef CONFIG_NET_CLS_ROUTE 427#ifdef CONFIG_IP_ROUTE_CLASSID
426 nla = nla_find(attrs, attrlen, RTA_FLOW); 428 nla = nla_find(attrs, attrlen, RTA_FLOW);
427 nexthop_nh->nh_tclassid = nla ? nla_get_u32(nla) : 0; 429 nexthop_nh->nh_tclassid = nla ? nla_get_u32(nla) : 0;
428#endif 430#endif
@@ -476,7 +478,7 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi)
476 nla = nla_find(attrs, attrlen, RTA_GATEWAY); 478 nla = nla_find(attrs, attrlen, RTA_GATEWAY);
477 if (nla && nla_get_be32(nla) != nh->nh_gw) 479 if (nla && nla_get_be32(nla) != nh->nh_gw)
478 return 1; 480 return 1;
479#ifdef CONFIG_NET_CLS_ROUTE 481#ifdef CONFIG_IP_ROUTE_CLASSID
480 nla = nla_find(attrs, attrlen, RTA_FLOW); 482 nla = nla_find(attrs, attrlen, RTA_FLOW);
481 if (nla && nla_get_u32(nla) != nh->nh_tclassid) 483 if (nla && nla_get_u32(nla) != nh->nh_tclassid)
482 return 1; 484 return 1;
@@ -742,6 +744,12 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
742 fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL); 744 fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
743 if (fi == NULL) 745 if (fi == NULL)
744 goto failure; 746 goto failure;
747 if (cfg->fc_mx) {
748 fi->fib_metrics = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL);
749 if (!fi->fib_metrics)
750 goto failure;
751 } else
752 fi->fib_metrics = (u32 *) dst_default_metrics;
745 fib_info_cnt++; 753 fib_info_cnt++;
746 754
747 fi->fib_net = hold_net(net); 755 fi->fib_net = hold_net(net);
@@ -779,7 +787,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
779 goto err_inval; 787 goto err_inval;
780 if (cfg->fc_gw && fi->fib_nh->nh_gw != cfg->fc_gw) 788 if (cfg->fc_gw && fi->fib_nh->nh_gw != cfg->fc_gw)
781 goto err_inval; 789 goto err_inval;
782#ifdef CONFIG_NET_CLS_ROUTE 790#ifdef CONFIG_IP_ROUTE_CLASSID
783 if (cfg->fc_flow && fi->fib_nh->nh_tclassid != cfg->fc_flow) 791 if (cfg->fc_flow && fi->fib_nh->nh_tclassid != cfg->fc_flow)
784 goto err_inval; 792 goto err_inval;
785#endif 793#endif
@@ -792,7 +800,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
792 nh->nh_oif = cfg->fc_oif; 800 nh->nh_oif = cfg->fc_oif;
793 nh->nh_gw = cfg->fc_gw; 801 nh->nh_gw = cfg->fc_gw;
794 nh->nh_flags = cfg->fc_flags; 802 nh->nh_flags = cfg->fc_flags;
795#ifdef CONFIG_NET_CLS_ROUTE 803#ifdef CONFIG_IP_ROUTE_CLASSID
796 nh->nh_tclassid = cfg->fc_flow; 804 nh->nh_tclassid = cfg->fc_flow;
797#endif 805#endif
798#ifdef CONFIG_IP_ROUTE_MULTIPATH 806#ifdef CONFIG_IP_ROUTE_MULTIPATH
@@ -1002,7 +1010,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
1002 1010
1003 if (fi->fib_nh->nh_oif) 1011 if (fi->fib_nh->nh_oif)
1004 NLA_PUT_U32(skb, RTA_OIF, fi->fib_nh->nh_oif); 1012 NLA_PUT_U32(skb, RTA_OIF, fi->fib_nh->nh_oif);
1005#ifdef CONFIG_NET_CLS_ROUTE 1013#ifdef CONFIG_IP_ROUTE_CLASSID
1006 if (fi->fib_nh[0].nh_tclassid) 1014 if (fi->fib_nh[0].nh_tclassid)
1007 NLA_PUT_U32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid); 1015 NLA_PUT_U32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid);
1008#endif 1016#endif
@@ -1027,7 +1035,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
1027 1035
1028 if (nh->nh_gw) 1036 if (nh->nh_gw)
1029 NLA_PUT_BE32(skb, RTA_GATEWAY, nh->nh_gw); 1037 NLA_PUT_BE32(skb, RTA_GATEWAY, nh->nh_gw);
1030#ifdef CONFIG_NET_CLS_ROUTE 1038#ifdef CONFIG_IP_ROUTE_CLASSID
1031 if (nh->nh_tclassid) 1039 if (nh->nh_tclassid)
1032 NLA_PUT_U32(skb, RTA_FLOW, nh->nh_tclassid); 1040 NLA_PUT_U32(skb, RTA_FLOW, nh->nh_tclassid);
1033#endif 1041#endif