@@ -2988,27 +2988,6 @@ static inline size_t neigh_nlmsg_size(void)
2988
2988
+ nla_total_size (1 ); /* NDA_PROTOCOL */
2989
2989
}
2990
2990
2991
- static int neigh_get_reply (struct net * net , struct neighbour * neigh ,
2992
- u32 pid , u32 seq )
2993
- {
2994
- struct sk_buff * skb ;
2995
- int err = 0 ;
2996
-
2997
- skb = nlmsg_new (neigh_nlmsg_size (), GFP_KERNEL );
2998
- if (!skb )
2999
- return - ENOBUFS ;
3000
-
3001
- err = neigh_fill_info (skb , neigh , pid , seq , RTM_NEWNEIGH , 0 );
3002
- if (err ) {
3003
- kfree_skb (skb );
3004
- goto errout ;
3005
- }
3006
-
3007
- err = rtnl_unicast (skb , net , pid );
3008
- errout :
3009
- return err ;
3010
- }
3011
-
3012
2991
static inline size_t pneigh_nlmsg_size (void )
3013
2992
{
3014
2993
return NLMSG_ALIGN (sizeof (struct ndmsg ))
@@ -3017,34 +2996,16 @@ static inline size_t pneigh_nlmsg_size(void)
3017
2996
+ nla_total_size (1 ); /* NDA_PROTOCOL */
3018
2997
}
3019
2998
3020
- static int pneigh_get_reply (struct net * net , struct pneigh_entry * neigh ,
3021
- u32 pid , u32 seq , struct neigh_table * tbl )
3022
- {
3023
- struct sk_buff * skb ;
3024
- int err = 0 ;
3025
-
3026
- skb = nlmsg_new (pneigh_nlmsg_size (), GFP_KERNEL );
3027
- if (!skb )
3028
- return - ENOBUFS ;
3029
-
3030
- err = pneigh_fill_info (skb , neigh , pid , seq , RTM_NEWNEIGH , 0 , tbl );
3031
- if (err ) {
3032
- kfree_skb (skb );
3033
- goto errout ;
3034
- }
3035
-
3036
- err = rtnl_unicast (skb , net , pid );
3037
- errout :
3038
- return err ;
3039
- }
3040
-
3041
2999
static int neigh_get (struct sk_buff * in_skb , struct nlmsghdr * nlh ,
3042
3000
struct netlink_ext_ack * extack )
3043
3001
{
3044
3002
struct net * net = sock_net (in_skb -> sk );
3003
+ u32 pid = NETLINK_CB (in_skb ).portid ;
3045
3004
struct net_device * dev = NULL ;
3046
3005
struct neigh_table * tbl = NULL ;
3006
+ u32 seq = nlh -> nlmsg_seq ;
3047
3007
struct neighbour * neigh ;
3008
+ struct sk_buff * skb ;
3048
3009
struct ndmsg * ndm ;
3049
3010
void * dst = NULL ;
3050
3011
int err ;
@@ -3053,11 +3014,19 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
3053
3014
if (IS_ERR (ndm ))
3054
3015
return PTR_ERR (ndm );
3055
3016
3017
+ if (ndm -> ndm_flags & NTF_PROXY )
3018
+ skb = nlmsg_new (neigh_nlmsg_size (), GFP_KERNEL );
3019
+ else
3020
+ skb = nlmsg_new (pneigh_nlmsg_size (), GFP_KERNEL );
3021
+ if (!skb )
3022
+ return - ENOBUFS ;
3023
+
3056
3024
if (ndm -> ndm_ifindex ) {
3057
3025
dev = __dev_get_by_index (net , ndm -> ndm_ifindex );
3058
3026
if (!dev ) {
3059
3027
NL_SET_ERR_MSG (extack , "Unknown device ifindex" );
3060
- return - ENODEV ;
3028
+ err = - ENODEV ;
3029
+ goto err_free_skb ;
3061
3030
}
3062
3031
}
3063
3032
@@ -3067,23 +3036,30 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
3067
3036
pn = pneigh_lookup (tbl , net , dst , dev , 0 );
3068
3037
if (!pn ) {
3069
3038
NL_SET_ERR_MSG (extack , "Proxy neighbour entry not found" );
3070
- return - ENOENT ;
3039
+ err = - ENOENT ;
3040
+ goto err_free_skb ;
3071
3041
}
3072
- return pneigh_get_reply (net , pn , NETLINK_CB (in_skb ).portid ,
3073
- nlh -> nlmsg_seq , tbl );
3074
- }
3075
-
3076
- neigh = neigh_lookup (tbl , dst , dev );
3077
- if (!neigh ) {
3078
- NL_SET_ERR_MSG (extack , "Neighbour entry not found" );
3079
- return - ENOENT ;
3080
- }
3081
3042
3082
- err = neigh_get_reply (net , neigh , NETLINK_CB (in_skb ).portid ,
3083
- nlh -> nlmsg_seq );
3043
+ err = pneigh_fill_info (skb , pn , pid , seq , RTM_NEWNEIGH , 0 , tbl );
3044
+ if (err )
3045
+ goto err_free_skb ;
3046
+ } else {
3047
+ neigh = neigh_lookup (tbl , dst , dev );
3048
+ if (!neigh ) {
3049
+ NL_SET_ERR_MSG (extack , "Neighbour entry not found" );
3050
+ err = - ENOENT ;
3051
+ goto err_free_skb ;
3052
+ }
3084
3053
3085
- neigh_release (neigh );
3054
+ err = neigh_fill_info (skb , neigh , pid , seq , RTM_NEWNEIGH , 0 );
3055
+ neigh_release (neigh );
3056
+ if (err )
3057
+ goto err_free_skb ;
3058
+ }
3086
3059
3060
+ return rtnl_unicast (skb , net , pid );
3061
+ err_free_skb :
3062
+ kfree_skb (skb );
3087
3063
return err ;
3088
3064
}
3089
3065
0 commit comments