aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_frontend.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/fib_frontend.c')
-rw-r--r--net/ipv4/fib_frontend.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 1fba6439fc57..cac06c43f004 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -493,6 +493,11 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
493 cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid; 493 cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
494 cfg->fc_nlinfo.nlh = nlh; 494 cfg->fc_nlinfo.nlh = nlh;
495 495
496 if (cfg->fc_type > RTN_MAX) {
497 err = -EINVAL;
498 goto errout;
499 }
500
496 nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) { 501 nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) {
497 switch (attr->nla_type) { 502 switch (attr->nla_type) {
498 case RTA_DST: 503 case RTA_DST:
@@ -771,6 +776,8 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
771 .nl_u = { .ip4_u = { .daddr = frn->fl_addr, 776 .nl_u = { .ip4_u = { .daddr = frn->fl_addr,
772 .tos = frn->fl_tos, 777 .tos = frn->fl_tos,
773 .scope = frn->fl_scope } } }; 778 .scope = frn->fl_scope } } };
779
780 frn->err = -ENOENT;
774 if (tb) { 781 if (tb) {
775 local_bh_disable(); 782 local_bh_disable();
776 783
@@ -782,6 +789,7 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
782 frn->nh_sel = res.nh_sel; 789 frn->nh_sel = res.nh_sel;
783 frn->type = res.type; 790 frn->type = res.type;
784 frn->scope = res.scope; 791 frn->scope = res.scope;
792 fib_res_put(&res);
785 } 793 }
786 local_bh_enable(); 794 local_bh_enable();
787 } 795 }
@@ -796,6 +804,9 @@ static void nl_fib_input(struct sock *sk, int len)
796 struct fib_table *tb; 804 struct fib_table *tb;
797 805
798 skb = skb_dequeue(&sk->sk_receive_queue); 806 skb = skb_dequeue(&sk->sk_receive_queue);
807 if (skb == NULL)
808 return;
809
799 nlh = (struct nlmsghdr *)skb->data; 810 nlh = (struct nlmsghdr *)skb->data;
800 if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len || 811 if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len ||
801 nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) { 812 nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) {
@@ -808,7 +819,7 @@ static void nl_fib_input(struct sock *sk, int len)
808 819
809 nl_fib_lookup(frn, tb); 820 nl_fib_lookup(frn, tb);
810 821
811 pid = nlh->nlmsg_pid; /*pid of sending process */ 822 pid = NETLINK_CB(skb).pid; /* pid of sending process */
812 NETLINK_CB(skb).pid = 0; /* from kernel */ 823 NETLINK_CB(skb).pid = 0; /* from kernel */
813 NETLINK_CB(skb).dst_group = 0; /* unicast */ 824 NETLINK_CB(skb).dst_group = 0; /* unicast */
814 netlink_unicast(sk, skb, pid, MSG_DONTWAIT); 825 netlink_unicast(sk, skb, pid, MSG_DONTWAIT);