@@ -281,6 +281,16 @@ nf_hook_entry_head(struct net *net, int pf, unsigned int hooknum,
281281 if (WARN_ON_ONCE (ARRAY_SIZE (net -> nf .hooks_bridge ) <= hooknum ))
282282 return NULL ;
283283 return net -> nf .hooks_bridge + hooknum ;
284+ #endif
285+ #ifdef CONFIG_NETFILTER_INGRESS
286+ case NFPROTO_INET :
287+ if (WARN_ON_ONCE (hooknum != NF_INET_INGRESS ))
288+ return NULL ;
289+ if (!dev || dev_net (dev ) != net ) {
290+ WARN_ON_ONCE (1 );
291+ return NULL ;
292+ }
293+ return & dev -> nf_hooks_ingress ;
284294#endif
285295 case NFPROTO_IPV4 :
286296 if (WARN_ON_ONCE (ARRAY_SIZE (net -> nf .hooks_ipv4 ) <= hooknum ))
@@ -311,22 +321,56 @@ nf_hook_entry_head(struct net *net, int pf, unsigned int hooknum,
311321 return NULL ;
312322}
313323
324+ static int nf_ingress_check (struct net * net , const struct nf_hook_ops * reg ,
325+ int hooknum )
326+ {
327+ #ifndef CONFIG_NETFILTER_INGRESS
328+ if (reg -> hooknum == hooknum )
329+ return - EOPNOTSUPP ;
330+ #endif
331+ if (reg -> hooknum != hooknum ||
332+ !reg -> dev || dev_net (reg -> dev ) != net )
333+ return - EINVAL ;
334+
335+ return 0 ;
336+ }
337+
314338static inline bool nf_ingress_hook (const struct nf_hook_ops * reg , int pf )
315339{
316- return pf == NFPROTO_NETDEV && reg -> hooknum == NF_NETDEV_INGRESS ;
340+ if ((pf == NFPROTO_NETDEV && reg -> hooknum == NF_NETDEV_INGRESS ) ||
341+ (pf == NFPROTO_INET && reg -> hooknum == NF_INET_INGRESS ))
342+ return true;
343+
344+ return false;
317345}
318346
319347static void nf_static_key_inc (const struct nf_hook_ops * reg , int pf )
320348{
321349#ifdef CONFIG_JUMP_LABEL
322- static_key_slow_inc (& nf_hooks_needed [pf ][reg -> hooknum ]);
350+ int hooknum ;
351+
352+ if (pf == NFPROTO_INET && reg -> hooknum == NF_INET_INGRESS ) {
353+ pf = NFPROTO_NETDEV ;
354+ hooknum = NF_NETDEV_INGRESS ;
355+ } else {
356+ hooknum = reg -> hooknum ;
357+ }
358+ static_key_slow_inc (& nf_hooks_needed [pf ][hooknum ]);
323359#endif
324360}
325361
326362static void nf_static_key_dec (const struct nf_hook_ops * reg , int pf )
327363{
328364#ifdef CONFIG_JUMP_LABEL
329- static_key_slow_dec (& nf_hooks_needed [pf ][reg -> hooknum ]);
365+ int hooknum ;
366+
367+ if (pf == NFPROTO_INET && reg -> hooknum == NF_INET_INGRESS ) {
368+ pf = NFPROTO_NETDEV ;
369+ hooknum = NF_NETDEV_INGRESS ;
370+ } else {
371+ hooknum = reg -> hooknum ;
372+ }
373+ static_key_slow_dec (& nf_hooks_needed [pf ][hooknum ]);
330374#endif
331375}
332376
@@ -335,15 +379,22 @@ static int __nf_register_net_hook(struct net *net, int pf,
335379{
336380 struct nf_hook_entries * p , * new_hooks ;
337381 struct nf_hook_entries __rcu * * pp ;
382+ int err ;
338383
339- if (pf == NFPROTO_NETDEV ) {
340- #ifndef CONFIG_NETFILTER_INGRESS
341- if (reg -> hooknum == NF_NETDEV_INGRESS )
342- return - EOPNOTSUPP ;
343- #endif
344- if (reg -> hooknum != NF_NETDEV_INGRESS ||
345- !reg -> dev || dev_net (reg -> dev ) != net )
346- return - EINVAL ;
384+ switch (pf ) {
385+ case NFPROTO_NETDEV :
386+ err = nf_ingress_check (net , reg , NF_NETDEV_INGRESS );
387+ if (err < 0 )
388+ return err ;
389+ break ;
390+ case NFPROTO_INET :
391+ if (reg -> hooknum != NF_INET_INGRESS )
392+ break ;
393+
394+ err = nf_ingress_check (net , reg , NF_INET_INGRESS );
395+ if (err < 0 )
396+ return err ;
397+ break ;
347398 }
348399
349400 pp = nf_hook_entry_head (net , pf , reg -> hooknum , reg -> dev );
@@ -441,8 +492,12 @@ static void __nf_unregister_net_hook(struct net *net, int pf,
441492void nf_unregister_net_hook (struct net * net , const struct nf_hook_ops * reg )
442493{
443494 if (reg -> pf == NFPROTO_INET ) {
444- __nf_unregister_net_hook (net , NFPROTO_IPV4 , reg );
445- __nf_unregister_net_hook (net , NFPROTO_IPV6 , reg );
495+ if (reg -> hooknum == NF_INET_INGRESS ) {
496+ __nf_unregister_net_hook (net , NFPROTO_INET , reg );
497+ } else {
498+ __nf_unregister_net_hook (net , NFPROTO_IPV4 , reg );
499+ __nf_unregister_net_hook (net , NFPROTO_IPV6 , reg );
500+ }
446501 } else {
447502 __nf_unregister_net_hook (net , reg -> pf , reg );
448503 }
@@ -467,14 +522,20 @@ int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg)
467522 int err ;
468523
469524 if (reg -> pf == NFPROTO_INET ) {
470- err = __nf_register_net_hook (net , NFPROTO_IPV4 , reg );
471- if (err < 0 )
472- return err ;
473-
474- err = __nf_register_net_hook (net , NFPROTO_IPV6 , reg );
475- if (err < 0 ) {
476- __nf_unregister_net_hook (net , NFPROTO_IPV4 , reg );
477- return err ;
525+ if (reg -> hooknum == NF_INET_INGRESS ) {
526+ err = __nf_register_net_hook (net , NFPROTO_INET , reg );
527+ if (err < 0 )
528+ return err ;
529+ } else {
530+ err = __nf_register_net_hook (net , NFPROTO_IPV4 , reg );
531+ if (err < 0 )
532+ return err ;
533+
534+ err = __nf_register_net_hook (net , NFPROTO_IPV6 , reg );
535+ if (err < 0 ) {
536+ __nf_unregister_net_hook (net , NFPROTO_IPV4 , reg );
537+ return err ;
538+ }
478539 }
479540 } else {
480541 err = __nf_register_net_hook (net , reg -> pf , reg );
0 commit comments