diff options
Diffstat (limited to 'net/ipv4/fib_frontend.c')
-rw-r--r-- | net/ipv4/fib_frontend.c | 13 |
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); |