LCOV - code coverage report
Current view: top level - include/net - route.h (source / functions) Hit Total Coverage
Test: combined.info Lines: 21 86 24.4 %
Date: 2022-04-01 14:17:54 Functions: 1 6 16.7 %
Branches: 7 108 6.5 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: GPL-2.0-or-later */
       2                 :            : /*
       3                 :            :  * INET         An implementation of the TCP/IP protocol suite for the LINUX
       4                 :            :  *              operating system.  INET  is implemented using the  BSD Socket
       5                 :            :  *              interface as the means of communication with the user level.
       6                 :            :  *
       7                 :            :  *              Definitions for the IP router.
       8                 :            :  *
       9                 :            :  * Version:     @(#)route.h     1.0.4   05/27/93
      10                 :            :  *
      11                 :            :  * Authors:     Ross Biro
      12                 :            :  *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
      13                 :            :  * Fixes:
      14                 :            :  *              Alan Cox        :       Reformatted. Added ip_rt_local()
      15                 :            :  *              Alan Cox        :       Support for TCP parameters.
      16                 :            :  *              Alexey Kuznetsov:       Major changes for new routing code.
      17                 :            :  *              Mike McLagan    :       Routing by source
      18                 :            :  *              Robert Olsson   :       Added rt_cache statistics
      19                 :            :  */
      20                 :            : #ifndef _ROUTE_H
      21                 :            : #define _ROUTE_H
      22                 :            : 
      23                 :            : #include <net/dst.h>
      24                 :            : #include <net/inetpeer.h>
      25                 :            : #include <net/flow.h>
      26                 :            : #include <net/inet_sock.h>
      27                 :            : #include <net/ip_fib.h>
      28                 :            : #include <net/arp.h>
      29                 :            : #include <net/ndisc.h>
      30                 :            : #include <linux/in_route.h>
      31                 :            : #include <linux/rtnetlink.h>
      32                 :            : #include <linux/rcupdate.h>
      33                 :            : #include <linux/route.h>
      34                 :            : #include <linux/ip.h>
      35                 :            : #include <linux/cache.h>
      36                 :            : #include <linux/security.h>
      37                 :            : 
      38                 :            : /* IPv4 datagram length is stored into 16bit field (tot_len) */
      39                 :            : #define IP_MAX_MTU      0xFFFFU
      40                 :            : 
      41                 :            : #define RTO_ONLINK      0x01
      42                 :            : 
      43                 :            : #define RT_CONN_FLAGS(sk)   (RT_TOS(inet_sk(sk)->tos) | sock_flag(sk, SOCK_LOCALROUTE))
      44                 :            : #define RT_CONN_FLAGS_TOS(sk,tos)   (RT_TOS(tos) | sock_flag(sk, SOCK_LOCALROUTE))
      45                 :            : 
      46                 :            : struct fib_nh;
      47                 :            : struct fib_info;
      48                 :            : struct uncached_list;
      49                 :            : struct rtable {
      50                 :            :         struct dst_entry        dst;
      51                 :            : 
      52                 :            :         int                     rt_genid;
      53                 :            :         unsigned int            rt_flags;
      54                 :            :         __u16                   rt_type;
      55                 :            :         __u8                    rt_is_input;
      56                 :            :         __u8                    rt_uses_gateway;
      57                 :            : 
      58                 :            :         int                     rt_iif;
      59                 :            : 
      60                 :            :         u8                      rt_gw_family;
      61                 :            :         /* Info on neighbour */
      62                 :            :         union {
      63                 :            :                 __be32          rt_gw4;
      64                 :            :                 struct in6_addr rt_gw6;
      65                 :            :         };
      66                 :            : 
      67                 :            :         /* Miscellaneous cached information */
      68                 :            :         u32                     rt_mtu_locked:1,
      69                 :            :                                 rt_pmtu:31;
      70                 :            : 
      71                 :            :         struct list_head        rt_uncached;
      72                 :            :         struct uncached_list    *rt_uncached_list;
      73                 :            : };
      74                 :            : 
      75                 :         11 : static inline bool rt_is_input_route(const struct rtable *rt)
      76                 :            : {
      77   [ -  -  -  -  :         11 :         return rt->rt_is_input != 0;
             -  +  -  - ]
      78                 :            : }
      79                 :            : 
      80                 :          0 : static inline bool rt_is_output_route(const struct rtable *rt)
      81                 :            : {
      82   [ #  #  #  #  :          0 :         return rt->rt_is_input == 0;
             #  #  #  # ]
      83                 :            : }
      84                 :            : 
      85                 :          0 : static inline __be32 rt_nexthop(const struct rtable *rt, __be32 daddr)
      86                 :            : {
      87   [ #  #  #  #  :          0 :         if (rt->rt_gw_family == AF_INET)
                   #  # ]
      88                 :          0 :                 return rt->rt_gw4;
      89                 :            :         return daddr;
      90                 :            : }
      91                 :            : 
      92                 :            : struct ip_rt_acct {
      93                 :            :         __u32   o_bytes;
      94                 :            :         __u32   o_packets;
      95                 :            :         __u32   i_bytes;
      96                 :            :         __u32   i_packets;
      97                 :            : };
      98                 :            : 
      99                 :            : struct rt_cache_stat {
     100                 :            :         unsigned int in_slow_tot;
     101                 :            :         unsigned int in_slow_mc;
     102                 :            :         unsigned int in_no_route;
     103                 :            :         unsigned int in_brd;
     104                 :            :         unsigned int in_martian_dst;
     105                 :            :         unsigned int in_martian_src;
     106                 :            :         unsigned int out_slow_tot;
     107                 :            :         unsigned int out_slow_mc;
     108                 :            : };
     109                 :            : 
     110                 :            : extern struct ip_rt_acct __percpu *ip_rt_acct;
     111                 :            : 
     112                 :            : struct in_device;
     113                 :            : 
     114                 :            : int ip_rt_init(void);
     115                 :            : void rt_cache_flush(struct net *net);
     116                 :            : void rt_flush_dev(struct net_device *dev);
     117                 :            : struct rtable *ip_route_output_key_hash(struct net *net, struct flowi4 *flp,
     118                 :            :                                         const struct sk_buff *skb);
     119                 :            : struct rtable *ip_route_output_key_hash_rcu(struct net *net, struct flowi4 *flp,
     120                 :            :                                             struct fib_result *res,
     121                 :            :                                             const struct sk_buff *skb);
     122                 :            : 
     123                 :        968 : static inline struct rtable *__ip_route_output_key(struct net *net,
     124                 :            :                                                    struct flowi4 *flp)
     125                 :            : {
     126                 :        968 :         return ip_route_output_key_hash(net, flp, NULL);
     127                 :            : }
     128                 :            : 
     129                 :            : struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
     130                 :            :                                     const struct sock *sk);
     131                 :            : struct dst_entry *ipv4_blackhole_route(struct net *net,
     132                 :            :                                        struct dst_entry *dst_orig);
     133                 :            : 
     134                 :          0 : static inline struct rtable *ip_route_output_key(struct net *net, struct flowi4 *flp)
     135                 :            : {
     136                 :          0 :         return ip_route_output_flow(net, flp, NULL);
     137                 :            : }
     138                 :            : 
     139                 :          0 : static inline struct rtable *ip_route_output(struct net *net, __be32 daddr,
     140                 :            :                                              __be32 saddr, u8 tos, int oif)
     141                 :            : {
     142                 :          0 :         struct flowi4 fl4 = {
     143                 :            :                 .flowi4_oif = oif,
     144                 :            :                 .flowi4_tos = tos,
     145                 :            :                 .daddr = daddr,
     146                 :            :                 .saddr = saddr,
     147                 :            :         };
     148                 :          0 :         return ip_route_output_key(net, &fl4);
     149                 :            : }
     150                 :            : 
     151                 :          0 : static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi4 *fl4,
     152                 :            :                                                    struct sock *sk,
     153                 :            :                                                    __be32 daddr, __be32 saddr,
     154                 :            :                                                    __be16 dport, __be16 sport,
     155                 :            :                                                    __u8 proto, __u8 tos, int oif)
     156                 :            : {
     157   [ #  #  #  #  :          0 :         flowi4_init_output(fl4, oif, sk ? sk->sk_mark : 0, tos,
                   #  # ]
     158                 :            :                            RT_SCOPE_UNIVERSE, proto,
     159                 :            :                            sk ? inet_sk_flowi_flags(sk) : 0,
     160                 :            :                            daddr, saddr, dport, sport, sock_net_uid(net, sk));
     161         [ #  # ]:          0 :         if (sk)
     162                 :          0 :                 security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
     163                 :          0 :         return ip_route_output_flow(net, fl4, sk);
     164                 :            : }
     165                 :            : 
     166                 :            : static inline struct rtable *ip_route_output_gre(struct net *net, struct flowi4 *fl4,
     167                 :            :                                                  __be32 daddr, __be32 saddr,
     168                 :            :                                                  __be32 gre_key, __u8 tos, int oif)
     169                 :            : {
     170                 :            :         memset(fl4, 0, sizeof(*fl4));
     171                 :            :         fl4->flowi4_oif = oif;
     172                 :            :         fl4->daddr = daddr;
     173                 :            :         fl4->saddr = saddr;
     174                 :            :         fl4->flowi4_tos = tos;
     175                 :            :         fl4->flowi4_proto = IPPROTO_GRE;
     176                 :            :         fl4->fl4_gre_key = gre_key;
     177                 :            :         return ip_route_output_key(net, fl4);
     178                 :            : }
     179                 :            : int ip_mc_validate_source(struct sk_buff *skb, __be32 daddr, __be32 saddr,
     180                 :            :                           u8 tos, struct net_device *dev,
     181                 :            :                           struct in_device *in_dev, u32 *itag);
     182                 :            : int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src,
     183                 :            :                          u8 tos, struct net_device *devin);
     184                 :            : int ip_route_input_rcu(struct sk_buff *skb, __be32 dst, __be32 src,
     185                 :            :                        u8 tos, struct net_device *devin,
     186                 :            :                        struct fib_result *res);
     187                 :            : 
     188                 :            : int ip_route_use_hint(struct sk_buff *skb, __be32 dst, __be32 src,
     189                 :            :                       u8 tos, struct net_device *devin,
     190                 :            :                       const struct sk_buff *hint);
     191                 :            : 
     192                 :          0 : static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src,
     193                 :            :                                  u8 tos, struct net_device *devin)
     194                 :            : {
     195                 :          0 :         int err;
     196                 :            : 
     197                 :          0 :         rcu_read_lock();
     198                 :          0 :         err = ip_route_input_noref(skb, dst, src, tos, devin);
     199         [ #  # ]:          0 :         if (!err) {
     200                 :          0 :                 skb_dst_force(skb);
     201         [ #  # ]:          0 :                 if (!skb_dst(skb))
     202                 :          0 :                         err = -EINVAL;
     203                 :            :         }
     204                 :          0 :         rcu_read_unlock();
     205                 :            : 
     206                 :          0 :         return err;
     207                 :            : }
     208                 :            : 
     209                 :            : void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, int oif,
     210                 :            :                       u8 protocol);
     211                 :            : void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu);
     212                 :            : void ipv4_redirect(struct sk_buff *skb, struct net *net, int oif, u8 protocol);
     213                 :            : void ipv4_sk_redirect(struct sk_buff *skb, struct sock *sk);
     214                 :            : void ip_rt_send_redirect(struct sk_buff *skb);
     215                 :            : 
     216                 :            : unsigned int inet_addr_type(struct net *net, __be32 addr);
     217                 :            : unsigned int inet_addr_type_table(struct net *net, __be32 addr, u32 tb_id);
     218                 :            : unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev,
     219                 :            :                                 __be32 addr);
     220                 :            : unsigned int inet_addr_type_dev_table(struct net *net,
     221                 :            :                                       const struct net_device *dev,
     222                 :            :                                       __be32 addr);
     223                 :            : void ip_rt_multicast_event(struct in_device *);
     224                 :            : int ip_rt_ioctl(struct net *, unsigned int cmd, struct rtentry *rt);
     225                 :            : void ip_rt_get_source(u8 *src, struct sk_buff *skb, struct rtable *rt);
     226                 :            : struct rtable *rt_dst_alloc(struct net_device *dev,
     227                 :            :                              unsigned int flags, u16 type,
     228                 :            :                              bool nopolicy, bool noxfrm, bool will_cache);
     229                 :            : struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt);
     230                 :            : 
     231                 :            : struct in_ifaddr;
     232                 :            : void fib_add_ifaddr(struct in_ifaddr *);
     233                 :            : void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *);
     234                 :            : void fib_modify_prefix_metric(struct in_ifaddr *ifa, u32 new_metric);
     235                 :            : 
     236                 :            : void rt_add_uncached_list(struct rtable *rt);
     237                 :            : void rt_del_uncached_list(struct rtable *rt);
     238                 :            : 
     239                 :            : int fib_dump_info_fnhe(struct sk_buff *skb, struct netlink_callback *cb,
     240                 :            :                        u32 table_id, struct fib_info *fi,
     241                 :            :                        int *fa_index, int fa_start, unsigned int flags);
     242                 :            : 
     243                 :         22 : static inline void ip_rt_put(struct rtable *rt)
     244                 :            : {
     245                 :            :         /* dst_release() accepts a NULL parameter.
     246                 :            :          * We rely on dst being first structure in struct rtable
     247                 :            :          */
     248                 :         22 :         BUILD_BUG_ON(offsetof(struct rtable, dst) != 0);
     249                 :          0 :         dst_release(&rt->dst);
     250                 :          0 : }
     251                 :            : 
     252                 :            : #define IPTOS_RT_MASK   (IPTOS_TOS_MASK & ~3)
     253                 :            : 
     254                 :            : extern const __u8 ip_tos2prio[16];
     255                 :            : 
     256                 :          0 : static inline char rt_tos2priority(u8 tos)
     257                 :            : {
     258                 :          0 :         return ip_tos2prio[IPTOS_TOS(tos)>>1];
     259                 :            : }
     260                 :            : 
     261                 :            : /* ip_route_connect() and ip_route_newports() work in tandem whilst
     262                 :            :  * binding a socket for a new outgoing connection.
     263                 :            :  *
     264                 :            :  * In order to use IPSEC properly, we must, in the end, have a
     265                 :            :  * route that was looked up using all available keys including source
     266                 :            :  * and destination ports.
     267                 :            :  *
     268                 :            :  * However, if a source port needs to be allocated (the user specified
     269                 :            :  * a wildcard source port) we need to obtain addressing information
     270                 :            :  * in order to perform that allocation.
     271                 :            :  *
     272                 :            :  * So ip_route_connect() looks up a route using wildcarded source and
     273                 :            :  * destination ports in the key, simply so that we can get a pair of
     274                 :            :  * addresses to use for port allocation.
     275                 :            :  *
     276                 :            :  * Later, once the ports are allocated, ip_route_newports() will make
     277                 :            :  * another route lookup if needed to make sure we catch any IPSEC
     278                 :            :  * rules keyed on the port information.
     279                 :            :  *
     280                 :            :  * The callers allocate the flow key on their stack, and must pass in
     281                 :            :  * the same flowi4 object to both the ip_route_connect() and the
     282                 :            :  * ip_route_newports() calls.
     283                 :            :  */
     284                 :            : 
     285                 :        946 : static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32 src,
     286                 :            :                                          u32 tos, int oif, u8 protocol,
     287                 :            :                                          __be16 sport, __be16 dport,
     288                 :            :                                          struct sock *sk)
     289                 :            : {
     290                 :        946 :         __u8 flow_flags = 0;
     291                 :            : 
     292                 :        946 :         if (inet_sk(sk)->transparent)
     293                 :          0 :                 flow_flags |= FLOWI_FLAG_ANYSRC;
     294                 :            : 
     295         [ +  - ]:        946 :         flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE,
     296                 :            :                            protocol, flow_flags, dst, src, dport, sport,
     297                 :            :                            sk->sk_uid);
     298                 :            : }
     299                 :            : 
     300                 :        946 : static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
     301                 :            :                                               __be32 dst, __be32 src, u32 tos,
     302                 :            :                                               int oif, u8 protocol,
     303                 :            :                                               __be16 sport, __be16 dport,
     304                 :            :                                               struct sock *sk)
     305                 :            : {
     306         [ -  + ]:        946 :         struct net *net = sock_net(sk);
     307                 :        946 :         struct rtable *rt;
     308                 :            : 
     309         [ -  + ]:        946 :         ip_route_connect_init(fl4, dst, src, tos, oif, protocol,
     310                 :            :                               sport, dport, sk);
     311                 :            : 
     312         [ +  - ]:        946 :         if (!dst || !src) {
     313                 :        946 :                 rt = __ip_route_output_key(net, fl4);
     314         [ +  + ]:        946 :                 if (IS_ERR(rt))
     315                 :            :                         return rt;
     316                 :         22 :                 ip_rt_put(rt);
     317                 :         22 :                 flowi4_update_output(fl4, oif, tos, fl4->daddr, fl4->saddr);
     318                 :            :         }
     319                 :         22 :         security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
     320                 :         22 :         return ip_route_output_flow(net, fl4, sk);
     321                 :            : }
     322                 :            : 
     323                 :          0 : static inline struct rtable *ip_route_newports(struct flowi4 *fl4, struct rtable *rt,
     324                 :            :                                                __be16 orig_sport, __be16 orig_dport,
     325                 :            :                                                __be16 sport, __be16 dport,
     326                 :            :                                                struct sock *sk)
     327                 :            : {
     328         [ #  # ]:          0 :         if (sport != orig_sport || dport != orig_dport) {
     329                 :          0 :                 fl4->fl4_dport = dport;
     330                 :          0 :                 fl4->fl4_sport = sport;
     331                 :          0 :                 ip_rt_put(rt);
     332                 :          0 :                 flowi4_update_output(fl4, sk->sk_bound_dev_if,
     333                 :          0 :                                      RT_CONN_FLAGS(sk), fl4->daddr,
     334                 :            :                                      fl4->saddr);
     335                 :          0 :                 security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
     336                 :          0 :                 return ip_route_output_flow(sock_net(sk), fl4, sk);
     337                 :            :         }
     338                 :            :         return rt;
     339                 :            : }
     340                 :            : 
     341                 :          0 : static inline int inet_iif(const struct sk_buff *skb)
     342                 :            : {
     343   [ #  #  #  #  :          0 :         struct rtable *rt = skb_rtable(skb);
          #  #  #  #  #  
                #  #  # ]
     344                 :            : 
     345   [ #  #  #  #  :          0 :         if (rt && rt->rt_iif)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     346                 :            :                 return rt->rt_iif;
     347                 :            : 
     348                 :          0 :         return skb->skb_iif;
     349                 :            : }
     350                 :            : 
     351                 :          0 : static inline int ip4_dst_hoplimit(const struct dst_entry *dst)
     352                 :            : {
     353   [ #  #  #  #  :          0 :         int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT);
                   #  # ]
     354   [ #  #  #  #  :          0 :         struct net *net = dev_net(dst->dev);
                   #  # ]
     355                 :            : 
     356   [ #  #  #  #  :          0 :         if (hoplimit == 0)
                   #  # ]
     357                 :          0 :                 hoplimit = net->ipv4.sysctl_ip_default_ttl;
     358                 :          0 :         return hoplimit;
     359                 :            : }
     360                 :            : 
     361                 :          0 : static inline struct neighbour *ip_neigh_gw4(struct net_device *dev,
     362                 :            :                                              __be32 daddr)
     363                 :            : {
     364                 :          0 :         struct neighbour *neigh;
     365                 :            : 
     366         [ #  # ]:          0 :         neigh = __ipv4_neigh_lookup_noref(dev, daddr);
     367         [ #  # ]:          0 :         if (unlikely(!neigh))
     368                 :          0 :                 neigh = __neigh_create(&arp_tbl, &daddr, dev, false);
     369                 :            : 
     370                 :          0 :         return neigh;
     371                 :            : }
     372                 :            : 
     373                 :          0 : static inline struct neighbour *ip_neigh_for_gw(struct rtable *rt,
     374                 :            :                                                 struct sk_buff *skb,
     375                 :            :                                                 bool *is_v6gw)
     376                 :            : {
     377                 :          0 :         struct net_device *dev = rt->dst.dev;
     378                 :          0 :         struct neighbour *neigh;
     379                 :            : 
     380         [ #  # ]:          0 :         if (likely(rt->rt_gw_family == AF_INET)) {
     381                 :          0 :                 neigh = ip_neigh_gw4(dev, rt->rt_gw4);
     382         [ #  # ]:          0 :         } else if (rt->rt_gw_family == AF_INET6) {
     383                 :          0 :                 neigh = ip_neigh_gw6(dev, &rt->rt_gw6);
     384                 :          0 :                 *is_v6gw = true;
     385                 :            :         } else {
     386                 :          0 :                 neigh = ip_neigh_gw4(dev, ip_hdr(skb)->daddr);
     387                 :            :         }
     388                 :          0 :         return neigh;
     389                 :            : }
     390                 :            : 
     391                 :            : #endif  /* _ROUTE_H */

Generated by: LCOV version 1.14