aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/fib_frontend.c4
-rw-r--r--net/ipv4/fib_hash.c2
-rw-r--r--net/ipv4/fib_lookup.h2
-rw-r--r--net/ipv4/fib_semantics.c88
-rw-r--r--net/ipv4/fib_trie.c2
-rw-r--r--net/ipv4/route.c68
6 files changed, 86 insertions, 80 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index acc18bdf2dee..d537c933abe3 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -591,8 +591,8 @@ int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
591 struct hlist_node *node; 591 struct hlist_node *node;
592 int dumped = 0; 592 int dumped = 0;
593 593
594 if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) && 594 if (nlmsg_len(cb->nlh) >= sizeof(struct rtmsg) &&
595 ((struct rtmsg*)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED) 595 ((struct rtmsg *) nlmsg_data(cb->nlh))->rtm_flags & RTM_F_CLONED)
596 return ip_rt_dump(skb, cb); 596 return ip_rt_dump(skb, cb);
597 597
598 s_h = cb->args[0]; 598 s_h = cb->args[0];
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 357557549ce5..88133b383dc5 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -693,7 +693,7 @@ fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb,
693 tb->tb_id, 693 tb->tb_id,
694 fa->fa_type, 694 fa->fa_type,
695 fa->fa_scope, 695 fa->fa_scope,
696 &f->fn_key, 696 f->fn_key,
697 fz->fz_order, 697 fz->fz_order,
698 fa->fa_tos, 698 fa->fa_tos,
699 fa->fa_info, 699 fa->fa_info,
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h
index d6d1a89e4003..fd6f7769f8ab 100644
--- a/net/ipv4/fib_lookup.h
+++ b/net/ipv4/fib_lookup.h
@@ -26,7 +26,7 @@ extern void fib_release_info(struct fib_info *);
26extern struct fib_info *fib_create_info(struct fib_config *cfg); 26extern struct fib_info *fib_create_info(struct fib_config *cfg);
27extern int fib_nh_match(struct fib_config *cfg, struct fib_info *fi); 27extern int fib_nh_match(struct fib_config *cfg, struct fib_info *fi);
28extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, 28extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
29 u32 tb_id, u8 type, u8 scope, void *dst, 29 u32 tb_id, u8 type, u8 scope, u32 dst,
30 int dst_len, u8 tos, struct fib_info *fi, 30 int dst_len, u8 tos, struct fib_info *fi,
31 unsigned int); 31 unsigned int);
32extern void rtmsg_fib(int event, u32 key, struct fib_alias *fa, 32extern void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 340f9db389e5..2ead09543f68 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -286,7 +286,7 @@ void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
286 goto errout; 286 goto errout;
287 287
288 err = fib_dump_info(skb, info->pid, seq, event, tb_id, 288 err = fib_dump_info(skb, info->pid, seq, event, tb_id,
289 fa->fa_type, fa->fa_scope, &key, dst_len, 289 fa->fa_type, fa->fa_scope, key, dst_len,
290 fa->fa_tos, fa->fa_info, 0); 290 fa->fa_tos, fa->fa_info, 0);
291 if (err < 0) { 291 if (err < 0) {
292 kfree_skb(skb); 292 kfree_skb(skb);
@@ -928,79 +928,87 @@ u32 __fib_res_prefsrc(struct fib_result *res)
928 return inet_select_addr(FIB_RES_DEV(*res), FIB_RES_GW(*res), res->scope); 928 return inet_select_addr(FIB_RES_DEV(*res), FIB_RES_GW(*res), res->scope);
929} 929}
930 930
931int 931int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
932fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, 932 u32 tb_id, u8 type, u8 scope, u32 dst, int dst_len, u8 tos,
933 u32 tb_id, u8 type, u8 scope, void *dst, int dst_len, u8 tos, 933 struct fib_info *fi, unsigned int flags)
934 struct fib_info *fi, unsigned int flags)
935{ 934{
935 struct nlmsghdr *nlh;
936 struct rtmsg *rtm; 936 struct rtmsg *rtm;
937 struct nlmsghdr *nlh;
938 unsigned char *b = skb->tail;
939 937
940 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags); 938 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags);
941 rtm = NLMSG_DATA(nlh); 939 if (nlh == NULL)
940 return -ENOBUFS;
941
942 rtm = nlmsg_data(nlh);
942 rtm->rtm_family = AF_INET; 943 rtm->rtm_family = AF_INET;
943 rtm->rtm_dst_len = dst_len; 944 rtm->rtm_dst_len = dst_len;
944 rtm->rtm_src_len = 0; 945 rtm->rtm_src_len = 0;
945 rtm->rtm_tos = tos; 946 rtm->rtm_tos = tos;
946 rtm->rtm_table = tb_id; 947 rtm->rtm_table = tb_id;
947 RTA_PUT_U32(skb, RTA_TABLE, tb_id); 948 NLA_PUT_U32(skb, RTA_TABLE, tb_id);
948 rtm->rtm_type = type; 949 rtm->rtm_type = type;
949 rtm->rtm_flags = fi->fib_flags; 950 rtm->rtm_flags = fi->fib_flags;
950 rtm->rtm_scope = scope; 951 rtm->rtm_scope = scope;
951 if (rtm->rtm_dst_len)
952 RTA_PUT(skb, RTA_DST, 4, dst);
953 rtm->rtm_protocol = fi->fib_protocol; 952 rtm->rtm_protocol = fi->fib_protocol;
953
954 if (rtm->rtm_dst_len)
955 NLA_PUT_U32(skb, RTA_DST, dst);
956
954 if (fi->fib_priority) 957 if (fi->fib_priority)
955 RTA_PUT(skb, RTA_PRIORITY, 4, &fi->fib_priority); 958 NLA_PUT_U32(skb, RTA_PRIORITY, fi->fib_priority);
959
956 if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0) 960 if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0)
957 goto rtattr_failure; 961 goto nla_put_failure;
962
958 if (fi->fib_prefsrc) 963 if (fi->fib_prefsrc)
959 RTA_PUT(skb, RTA_PREFSRC, 4, &fi->fib_prefsrc); 964 NLA_PUT_U32(skb, RTA_PREFSRC, fi->fib_prefsrc);
965
960 if (fi->fib_nhs == 1) { 966 if (fi->fib_nhs == 1) {
961 if (fi->fib_nh->nh_gw) 967 if (fi->fib_nh->nh_gw)
962 RTA_PUT(skb, RTA_GATEWAY, 4, &fi->fib_nh->nh_gw); 968 NLA_PUT_U32(skb, RTA_GATEWAY, fi->fib_nh->nh_gw);
969
963 if (fi->fib_nh->nh_oif) 970 if (fi->fib_nh->nh_oif)
964 RTA_PUT(skb, RTA_OIF, sizeof(int), &fi->fib_nh->nh_oif); 971 NLA_PUT_U32(skb, RTA_OIF, fi->fib_nh->nh_oif);
965#ifdef CONFIG_NET_CLS_ROUTE 972#ifdef CONFIG_NET_CLS_ROUTE
966 if (fi->fib_nh[0].nh_tclassid) 973 if (fi->fib_nh[0].nh_tclassid)
967 RTA_PUT(skb, RTA_FLOW, 4, &fi->fib_nh[0].nh_tclassid); 974 NLA_PUT_U32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid);
968#endif 975#endif
969 } 976 }
970#ifdef CONFIG_IP_ROUTE_MULTIPATH 977#ifdef CONFIG_IP_ROUTE_MULTIPATH
971 if (fi->fib_nhs > 1) { 978 if (fi->fib_nhs > 1) {
972 struct rtnexthop *nhp; 979 struct rtnexthop *rtnh;
973 struct rtattr *mp_head; 980 struct nlattr *mp;
974 if (skb_tailroom(skb) <= RTA_SPACE(0)) 981
975 goto rtattr_failure; 982 mp = nla_nest_start(skb, RTA_MULTIPATH);
976 mp_head = (struct rtattr*)skb_put(skb, RTA_SPACE(0)); 983 if (mp == NULL)
984 goto nla_put_failure;
977 985
978 for_nexthops(fi) { 986 for_nexthops(fi) {
979 if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) 987 rtnh = nla_reserve_nohdr(skb, sizeof(*rtnh));
980 goto rtattr_failure; 988 if (rtnh == NULL)
981 nhp = (struct rtnexthop*)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); 989 goto nla_put_failure;
982 nhp->rtnh_flags = nh->nh_flags & 0xFF; 990
983 nhp->rtnh_hops = nh->nh_weight-1; 991 rtnh->rtnh_flags = nh->nh_flags & 0xFF;
984 nhp->rtnh_ifindex = nh->nh_oif; 992 rtnh->rtnh_hops = nh->nh_weight - 1;
993 rtnh->rtnh_ifindex = nh->nh_oif;
994
985 if (nh->nh_gw) 995 if (nh->nh_gw)
986 RTA_PUT(skb, RTA_GATEWAY, 4, &nh->nh_gw); 996 NLA_PUT_U32(skb, RTA_GATEWAY, nh->nh_gw);
987#ifdef CONFIG_NET_CLS_ROUTE 997#ifdef CONFIG_NET_CLS_ROUTE
988 if (nh->nh_tclassid) 998 if (nh->nh_tclassid)
989 RTA_PUT(skb, RTA_FLOW, 4, &nh->nh_tclassid); 999 NLA_PUT_U32(skb, RTA_FLOW, nh->nh_tclassid);
990#endif 1000#endif
991 nhp->rtnh_len = skb->tail - (unsigned char*)nhp; 1001 /* length of rtnetlink header + attributes */
1002 rtnh->rtnh_len = nlmsg_get_pos(skb) - (void *) rtnh;
992 } endfor_nexthops(fi); 1003 } endfor_nexthops(fi);
993 mp_head->rta_type = RTA_MULTIPATH; 1004
994 mp_head->rta_len = skb->tail - (u8*)mp_head; 1005 nla_nest_end(skb, mp);
995 } 1006 }
996#endif 1007#endif
997 nlh->nlmsg_len = skb->tail - b; 1008 return nlmsg_end(skb, nlh);
998 return skb->len;
999 1009
1000nlmsg_failure: 1010nla_put_failure:
1001rtattr_failure: 1011 return nlmsg_cancel(skb, nlh);
1002 skb_trim(skb, b - skb->data);
1003 return -1;
1004} 1012}
1005 1013
1006/* 1014/*
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 41bef0a88ab6..9c3ff6ba6e21 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1854,7 +1854,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fi
1854 tb->tb_id, 1854 tb->tb_id,
1855 fa->fa_type, 1855 fa->fa_type,
1856 fa->fa_scope, 1856 fa->fa_scope,
1857 &xkey, 1857 xkey,
1858 plen, 1858 plen,
1859 fa->fa_tos, 1859 fa->fa_tos,
1860 fa->fa_info, 0) < 0) { 1860 fa->fa_info, 0) < 0) {
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index b8f6cadc5b3a..31b67059ac29 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2639,52 +2639,54 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2639{ 2639{
2640 struct rtable *rt = (struct rtable*)skb->dst; 2640 struct rtable *rt = (struct rtable*)skb->dst;
2641 struct rtmsg *r; 2641 struct rtmsg *r;
2642 struct nlmsghdr *nlh; 2642 struct nlmsghdr *nlh;
2643 unsigned char *b = skb->tail;
2644 struct rta_cacheinfo ci; 2643 struct rta_cacheinfo ci;
2645#ifdef CONFIG_IP_MROUTE 2644
2646 struct rtattr *eptr; 2645 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags);
2647#endif 2646 if (nlh == NULL)
2648 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); 2647 return -ENOBUFS;
2649 r = NLMSG_DATA(nlh); 2648
2649 r = nlmsg_data(nlh);
2650 r->rtm_family = AF_INET; 2650 r->rtm_family = AF_INET;
2651 r->rtm_dst_len = 32; 2651 r->rtm_dst_len = 32;
2652 r->rtm_src_len = 0; 2652 r->rtm_src_len = 0;
2653 r->rtm_tos = rt->fl.fl4_tos; 2653 r->rtm_tos = rt->fl.fl4_tos;
2654 r->rtm_table = RT_TABLE_MAIN; 2654 r->rtm_table = RT_TABLE_MAIN;
2655 RTA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN); 2655 NLA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN);
2656 r->rtm_type = rt->rt_type; 2656 r->rtm_type = rt->rt_type;
2657 r->rtm_scope = RT_SCOPE_UNIVERSE; 2657 r->rtm_scope = RT_SCOPE_UNIVERSE;
2658 r->rtm_protocol = RTPROT_UNSPEC; 2658 r->rtm_protocol = RTPROT_UNSPEC;
2659 r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED; 2659 r->rtm_flags = (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED;
2660 if (rt->rt_flags & RTCF_NOTIFY) 2660 if (rt->rt_flags & RTCF_NOTIFY)
2661 r->rtm_flags |= RTM_F_NOTIFY; 2661 r->rtm_flags |= RTM_F_NOTIFY;
2662 RTA_PUT(skb, RTA_DST, 4, &rt->rt_dst); 2662
2663 NLA_PUT_U32(skb, RTA_DST, rt->rt_dst);
2664
2663 if (rt->fl.fl4_src) { 2665 if (rt->fl.fl4_src) {
2664 r->rtm_src_len = 32; 2666 r->rtm_src_len = 32;
2665 RTA_PUT(skb, RTA_SRC, 4, &rt->fl.fl4_src); 2667 NLA_PUT_U32(skb, RTA_SRC, rt->fl.fl4_src);
2666 } 2668 }
2667 if (rt->u.dst.dev) 2669 if (rt->u.dst.dev)
2668 RTA_PUT(skb, RTA_OIF, sizeof(int), &rt->u.dst.dev->ifindex); 2670 NLA_PUT_U32(skb, RTA_OIF, rt->u.dst.dev->ifindex);
2669#ifdef CONFIG_NET_CLS_ROUTE 2671#ifdef CONFIG_NET_CLS_ROUTE
2670 if (rt->u.dst.tclassid) 2672 if (rt->u.dst.tclassid)
2671 RTA_PUT(skb, RTA_FLOW, 4, &rt->u.dst.tclassid); 2673 NLA_PUT_U32(skb, RTA_FLOW, rt->u.dst.tclassid);
2672#endif 2674#endif
2673#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 2675#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
2674 if (rt->rt_multipath_alg != IP_MP_ALG_NONE) { 2676 if (rt->rt_multipath_alg != IP_MP_ALG_NONE)
2675 __u32 alg = rt->rt_multipath_alg; 2677 NLA_PUT_U32(skb, RTA_MP_ALGO, rt->rt_multipath_alg);
2676
2677 RTA_PUT(skb, RTA_MP_ALGO, 4, &alg);
2678 }
2679#endif 2678#endif
2680 if (rt->fl.iif) 2679 if (rt->fl.iif)
2681 RTA_PUT(skb, RTA_PREFSRC, 4, &rt->rt_spec_dst); 2680 NLA_PUT_U32(skb, RTA_PREFSRC, rt->rt_spec_dst);
2682 else if (rt->rt_src != rt->fl.fl4_src) 2681 else if (rt->rt_src != rt->fl.fl4_src)
2683 RTA_PUT(skb, RTA_PREFSRC, 4, &rt->rt_src); 2682 NLA_PUT_U32(skb, RTA_PREFSRC, rt->rt_src);
2683
2684 if (rt->rt_dst != rt->rt_gateway) 2684 if (rt->rt_dst != rt->rt_gateway)
2685 RTA_PUT(skb, RTA_GATEWAY, 4, &rt->rt_gateway); 2685 NLA_PUT_U32(skb, RTA_GATEWAY, rt->rt_gateway);
2686
2686 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0) 2687 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
2687 goto rtattr_failure; 2688 goto nla_put_failure;
2689
2688 ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse); 2690 ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse);
2689 ci.rta_used = rt->u.dst.__use; 2691 ci.rta_used = rt->u.dst.__use;
2690 ci.rta_clntref = atomic_read(&rt->u.dst.__refcnt); 2692 ci.rta_clntref = atomic_read(&rt->u.dst.__refcnt);
@@ -2701,10 +2703,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2701 ci.rta_tsage = xtime.tv_sec - rt->peer->tcp_ts_stamp; 2703 ci.rta_tsage = xtime.tv_sec - rt->peer->tcp_ts_stamp;
2702 } 2704 }
2703 } 2705 }
2704#ifdef CONFIG_IP_MROUTE 2706
2705 eptr = (struct rtattr*)skb->tail;
2706#endif
2707 RTA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci);
2708 if (rt->fl.iif) { 2707 if (rt->fl.iif) {
2709#ifdef CONFIG_IP_MROUTE 2708#ifdef CONFIG_IP_MROUTE
2710 u32 dst = rt->rt_dst; 2709 u32 dst = rt->rt_dst;
@@ -2716,25 +2715,24 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2716 if (!nowait) { 2715 if (!nowait) {
2717 if (err == 0) 2716 if (err == 0)
2718 return 0; 2717 return 0;
2719 goto nlmsg_failure; 2718 goto nla_put_failure;
2720 } else { 2719 } else {
2721 if (err == -EMSGSIZE) 2720 if (err == -EMSGSIZE)
2722 goto nlmsg_failure; 2721 goto nla_put_failure;
2723 ((struct rta_cacheinfo*)RTA_DATA(eptr))->rta_error = err; 2722 ci.rta_error = err;
2724 } 2723 }
2725 } 2724 }
2726 } else 2725 } else
2727#endif 2726#endif
2728 RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif); 2727 NLA_PUT_U32(skb, RTA_IIF, rt->fl.iif);
2729 } 2728 }
2730 2729
2731 nlh->nlmsg_len = skb->tail - b; 2730 NLA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci);
2732 return skb->len; 2731
2732 return nlmsg_end(skb, nlh);
2733 2733
2734nlmsg_failure: 2734nla_put_failure:
2735rtattr_failure: 2735 return nlmsg_cancel(skb, nlh);
2736 skb_trim(skb, b - skb->data);
2737 return -1;
2738} 2736}
2739 2737
2740int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) 2738int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)