LCOV - code coverage report
Current view: top level - include/net - route.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 32 38 84.2 %
Date: 2014-04-07 Functions: 0 0 -
Branches: 19 55 34.5 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * INET         An implementation of the TCP/IP protocol suite for the LINUX
       3                 :            :  *              operating system.  INET  is implemented using the  BSD Socket
       4                 :            :  *              interface as the means of communication with the user level.
       5                 :            :  *
       6                 :            :  *              Definitions for the IP router.
       7                 :            :  *
       8                 :            :  * Version:     @(#)route.h     1.0.4   05/27/93
       9                 :            :  *
      10                 :            :  * Authors:     Ross Biro
      11                 :            :  *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
      12                 :            :  * Fixes:
      13                 :            :  *              Alan Cox        :       Reformatted. Added ip_rt_local()
      14                 :            :  *              Alan Cox        :       Support for TCP parameters.
      15                 :            :  *              Alexey Kuznetsov:       Major changes for new routing code.
      16                 :            :  *              Mike McLagan    :       Routing by source
      17                 :            :  *              Robert Olsson   :       Added rt_cache statistics
      18                 :            :  *
      19                 :            :  *              This program is free software; you can redistribute it and/or
      20                 :            :  *              modify it under the terms of the GNU General Public License
      21                 :            :  *              as published by the Free Software Foundation; either version
      22                 :            :  *              2 of the License, or (at your option) any later version.
      23                 :            :  */
      24                 :            : #ifndef _ROUTE_H
      25                 :            : #define _ROUTE_H
      26                 :            : 
      27                 :            : #include <net/dst.h>
      28                 :            : #include <net/inetpeer.h>
      29                 :            : #include <net/flow.h>
      30                 :            : #include <net/inet_sock.h>
      31                 :            : #include <linux/in_route.h>
      32                 :            : #include <linux/rtnetlink.h>
      33                 :            : #include <linux/rcupdate.h>
      34                 :            : #include <linux/route.h>
      35                 :            : #include <linux/ip.h>
      36                 :            : #include <linux/cache.h>
      37                 :            : #include <linux/security.h>
      38                 :            : 
      39                 :            : #define RTO_ONLINK      0x01
      40                 :            : 
      41                 :            : #define RT_CONN_FLAGS(sk)   (RT_TOS(inet_sk(sk)->tos) | sock_flag(sk, SOCK_LOCALROUTE))
      42                 :            : #define RT_CONN_FLAGS_TOS(sk,tos)   (RT_TOS(tos) | sock_flag(sk, SOCK_LOCALROUTE))
      43                 :            : 
      44                 :            : struct fib_nh;
      45                 :            : struct fib_info;
      46                 :            : struct rtable {
      47                 :            :         struct dst_entry        dst;
      48                 :            : 
      49                 :            :         int                     rt_genid;
      50                 :            :         unsigned int            rt_flags;
      51                 :            :         __u16                   rt_type;
      52                 :            :         __u8                    rt_is_input;
      53                 :            :         __u8                    rt_uses_gateway;
      54                 :            : 
      55                 :            :         int                     rt_iif;
      56                 :            : 
      57                 :            :         /* Info on neighbour */
      58                 :            :         __be32                  rt_gateway;
      59                 :            : 
      60                 :            :         /* Miscellaneous cached information */
      61                 :            :         u32                     rt_pmtu;
      62                 :            : 
      63                 :            :         struct list_head        rt_uncached;
      64                 :            : };
      65                 :            : 
      66                 :            : static inline bool rt_is_input_route(const struct rtable *rt)
      67                 :            : {
      68                 :            :         return rt->rt_is_input != 0;
      69                 :            : }
      70                 :            : 
      71                 :            : static inline bool rt_is_output_route(const struct rtable *rt)
      72                 :            : {
      73                 :            :         return rt->rt_is_input == 0;
      74                 :            : }
      75                 :            : 
      76                 :            : static inline __be32 rt_nexthop(const struct rtable *rt, __be32 daddr)
      77                 :            : {
      78         [ +  + ]:      54526 :         if (rt->rt_gateway)
           [ #  #  #  # ]
         [ #  # ][ #  # ]
      79                 :            :                 return rt->rt_gateway;
      80                 :            :         return daddr;
      81                 :            : }
      82                 :            : 
      83                 :            : struct ip_rt_acct {
      84                 :            :         __u32   o_bytes;
      85                 :            :         __u32   o_packets;
      86                 :            :         __u32   i_bytes;
      87                 :            :         __u32   i_packets;
      88                 :            : };
      89                 :            : 
      90                 :            : struct rt_cache_stat {
      91                 :            :         unsigned int in_slow_tot;
      92                 :            :         unsigned int in_slow_mc;
      93                 :            :         unsigned int in_no_route;
      94                 :            :         unsigned int in_brd;
      95                 :            :         unsigned int in_martian_dst;
      96                 :            :         unsigned int in_martian_src;
      97                 :            :         unsigned int out_slow_tot;
      98                 :            :         unsigned int out_slow_mc;
      99                 :            : };
     100                 :            : 
     101                 :            : extern struct ip_rt_acct __percpu *ip_rt_acct;
     102                 :            : 
     103                 :            : struct in_device;
     104                 :            : 
     105                 :            : int ip_rt_init(void);
     106                 :            : void rt_cache_flush(struct net *net);
     107                 :            : void rt_flush_dev(struct net_device *dev);
     108                 :            : struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp);
     109                 :            : struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
     110                 :            :                                     struct sock *sk);
     111                 :            : struct dst_entry *ipv4_blackhole_route(struct net *net,
     112                 :            :                                        struct dst_entry *dst_orig);
     113                 :            : 
     114                 :            : static inline struct rtable *ip_route_output_key(struct net *net, struct flowi4 *flp)
     115                 :            : {
     116                 :          3 :         return ip_route_output_flow(net, flp, NULL);
     117                 :            : }
     118                 :            : 
     119                 :            : static inline struct rtable *ip_route_output(struct net *net, __be32 daddr,
     120                 :            :                                              __be32 saddr, u8 tos, int oif)
     121                 :            : {
     122                 :          0 :         struct flowi4 fl4 = {
     123                 :            :                 .flowi4_oif = oif,
     124                 :            :                 .flowi4_tos = tos,
     125                 :            :                 .daddr = daddr,
     126                 :            :                 .saddr = saddr,
     127                 :            :         };
     128                 :            :         return ip_route_output_key(net, &fl4);
     129                 :            : }
     130                 :            : 
     131                 :            : static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi4 *fl4,
     132                 :            :                                                    struct sock *sk,
     133                 :            :                                                    __be32 daddr, __be32 saddr,
     134                 :            :                                                    __be16 dport, __be16 sport,
     135                 :            :                                                    __u8 proto, __u8 tos, int oif)
     136                 :            : {
     137 [ +  - ][ +  - ]:          2 :         flowi4_init_output(fl4, oif, sk ? sk->sk_mark : 0, tos,
         [ #  # ][ #  # ]
     138                 :            :                            RT_SCOPE_UNIVERSE, proto,
     139                 :            :                            sk ? inet_sk_flowi_flags(sk) : 0,
     140                 :            :                            daddr, saddr, dport, sport);
     141    [ +  - ][ - ]:          2 :         if (sk)
     142                 :          2 :                 security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
     143                 :          2 :         return ip_route_output_flow(net, fl4, sk);
     144                 :            : }
     145                 :            : 
     146                 :            : static inline struct rtable *ip_route_output_gre(struct net *net, struct flowi4 *fl4,
     147                 :            :                                                  __be32 daddr, __be32 saddr,
     148                 :            :                                                  __be32 gre_key, __u8 tos, int oif)
     149                 :            : {
     150                 :            :         memset(fl4, 0, sizeof(*fl4));
     151                 :            :         fl4->flowi4_oif = oif;
     152                 :            :         fl4->daddr = daddr;
     153                 :            :         fl4->saddr = saddr;
     154                 :            :         fl4->flowi4_tos = tos;
     155                 :            :         fl4->flowi4_proto = IPPROTO_GRE;
     156                 :            :         fl4->fl4_gre_key = gre_key;
     157                 :            :         return ip_route_output_key(net, fl4);
     158                 :            : }
     159                 :            : 
     160                 :            : int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src,
     161                 :            :                          u8 tos, struct net_device *devin);
     162                 :            : 
     163                 :            : static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src,
     164                 :            :                                  u8 tos, struct net_device *devin)
     165                 :            : {
     166                 :            :         int err;
     167                 :            : 
     168                 :            :         rcu_read_lock();
     169                 :          0 :         err = ip_route_input_noref(skb, dst, src, tos, devin);
     170         [ #  # ]:          0 :         if (!err)
     171                 :            :                 skb_dst_force(skb);
     172                 :            :         rcu_read_unlock();
     173                 :            : 
     174                 :            :         return err;
     175                 :            : }
     176                 :            : 
     177                 :            : void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, int oif,
     178                 :            :                       u32 mark, u8 protocol, int flow_flags);
     179                 :            : void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu);
     180                 :            : void ipv4_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark,
     181                 :            :                    u8 protocol, int flow_flags);
     182                 :            : void ipv4_sk_redirect(struct sk_buff *skb, struct sock *sk);
     183                 :            : void ip_rt_send_redirect(struct sk_buff *skb);
     184                 :            : 
     185                 :            : unsigned int inet_addr_type(struct net *net, __be32 addr);
     186                 :            : unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev,
     187                 :            :                                 __be32 addr);
     188                 :            : void ip_rt_multicast_event(struct in_device *);
     189                 :            : int ip_rt_ioctl(struct net *, unsigned int cmd, void __user *arg);
     190                 :            : void ip_rt_get_source(u8 *src, struct sk_buff *skb, struct rtable *rt);
     191                 :            : int ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb);
     192                 :            : 
     193                 :            : struct in_ifaddr;
     194                 :            : void fib_add_ifaddr(struct in_ifaddr *);
     195                 :            : void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *);
     196                 :            : 
     197                 :            : static inline void ip_rt_put(struct rtable *rt)
     198                 :            : {
     199                 :            :         /* dst_release() accepts a NULL parameter.
     200                 :            :          * We rely on dst being first structure in struct rtable
     201                 :            :          */
     202                 :            :         BUILD_BUG_ON(offsetof(struct rtable, dst) != 0);
     203                 :        130 :         dst_release(&rt->dst);
     204                 :            : }
     205                 :            : 
     206                 :            : #define IPTOS_RT_MASK   (IPTOS_TOS_MASK & ~3)
     207                 :            : 
     208                 :            : extern const __u8 ip_tos2prio[16];
     209                 :            : 
     210                 :            : static inline char rt_tos2priority(u8 tos)
     211                 :            : {
     212                 :          2 :         return ip_tos2prio[IPTOS_TOS(tos)>>1];
     213                 :            : }
     214                 :            : 
     215                 :            : /* ip_route_connect() and ip_route_newports() work in tandem whilst
     216                 :            :  * binding a socket for a new outgoing connection.
     217                 :            :  *
     218                 :            :  * In order to use IPSEC properly, we must, in the end, have a
     219                 :            :  * route that was looked up using all available keys including source
     220                 :            :  * and destination ports.
     221                 :            :  *
     222                 :            :  * However, if a source port needs to be allocated (the user specified
     223                 :            :  * a wildcard source port) we need to obtain addressing information
     224                 :            :  * in order to perform that allocation.
     225                 :            :  *
     226                 :            :  * So ip_route_connect() looks up a route using wildcarded source and
     227                 :            :  * destination ports in the key, simply so that we can get a pair of
     228                 :            :  * addresses to use for port allocation.
     229                 :            :  *
     230                 :            :  * Later, once the ports are allocated, ip_route_newports() will make
     231                 :            :  * another route lookup if needed to make sure we catch any IPSEC
     232                 :            :  * rules keyed on the port information.
     233                 :            :  *
     234                 :            :  * The callers allocate the flow key on their stack, and must pass in
     235                 :            :  * the same flowi4 object to both the ip_route_connect() and the
     236                 :            :  * ip_route_newports() calls.
     237                 :            :  */
     238                 :            : 
     239                 :            : static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32 src,
     240                 :            :                                          u32 tos, int oif, u8 protocol,
     241                 :            :                                          __be16 sport, __be16 dport,
     242                 :            :                                          struct sock *sk, bool can_sleep)
     243                 :            : {
     244                 :            :         __u8 flow_flags = 0;
     245                 :            : 
     246         [ -  + ]:         68 :         if (inet_sk(sk)->transparent)
     247                 :            :                 flow_flags |= FLOWI_FLAG_ANYSRC;
     248                 :            :         if (can_sleep)
     249                 :         68 :                 flow_flags |= FLOWI_FLAG_CAN_SLEEP;
     250                 :            : 
     251                 :         68 :         flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE,
     252                 :            :                            protocol, flow_flags, dst, src, dport, sport);
     253                 :            : }
     254                 :            : 
     255                 :            : static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
     256                 :            :                                               __be32 dst, __be32 src, u32 tos,
     257                 :            :                                               int oif, u8 protocol,
     258                 :            :                                               __be16 sport, __be16 dport,
     259                 :            :                                               struct sock *sk, bool can_sleep)
     260                 :            : {
     261                 :            :         struct net *net = sock_net(sk);
     262                 :            :         struct rtable *rt;
     263                 :            : 
     264                 :            :         ip_route_connect_init(fl4, dst, src, tos, oif, protocol,
     265                 :            :                               sport, dport, sk, can_sleep);
     266                 :            : 
     267         [ +  - ]:         68 :         if (!dst || !src) {
     268                 :         68 :                 rt = __ip_route_output_key(net, fl4);
     269         [ +  - ]:         68 :                 if (IS_ERR(rt))
     270                 :            :                         return rt;
     271                 :            :                 ip_rt_put(rt);
     272                 :            :                 flowi4_update_output(fl4, oif, tos, fl4->daddr, fl4->saddr);
     273                 :            :         }
     274                 :         68 :         security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
     275                 :         68 :         return ip_route_output_flow(net, fl4, sk);
     276                 :            : }
     277                 :            : 
     278                 :            : static inline struct rtable *ip_route_newports(struct flowi4 *fl4, struct rtable *rt,
     279                 :            :                                                __be16 orig_sport, __be16 orig_dport,
     280                 :            :                                                __be16 sport, __be16 dport,
     281                 :            :                                                struct sock *sk)
     282                 :            : {
     283         [ +  - ]:         30 :         if (sport != orig_sport || dport != orig_dport) {
     284                 :         30 :                 fl4->fl4_dport = dport;
     285                 :         30 :                 fl4->fl4_sport = sport;
     286                 :            :                 ip_rt_put(rt);
     287                 :         90 :                 flowi4_update_output(fl4, sk->sk_bound_dev_if,
     288                 :         30 :                                      RT_CONN_FLAGS(sk), fl4->daddr,
     289                 :            :                                      fl4->saddr);
     290                 :         30 :                 security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
     291                 :         30 :                 return ip_route_output_flow(sock_net(sk), fl4, sk);
     292                 :            :         }
     293                 :            :         return rt;
     294                 :            : }
     295                 :            : 
     296                 :            : static inline int inet_iif(const struct sk_buff *skb)
     297                 :            : {
     298                 :        821 :         int iif = skb_rtable(skb)->rt_iif;
     299                 :            : 
     300 [ +  - ][ #  # ]:        821 :         if (iif)
           [ +  -  +  - ]
                 [ #  # ]
     301                 :            :                 return iif;
     302                 :        821 :         return skb->skb_iif;
     303                 :            : }
     304                 :            : 
     305                 :            : extern int sysctl_ip_default_ttl;
     306                 :            : 
     307                 :      54528 : static inline int ip4_dst_hoplimit(const struct dst_entry *dst)
     308                 :            : {
     309                 :      54528 :         int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT);
     310                 :            : 
     311 [ +  - ][ +  + ]:      54528 :         if (hoplimit == 0)
                 [ +  - ]
     312                 :      54527 :                 hoplimit = sysctl_ip_default_ttl;
     313                 :            :         return hoplimit;
     314                 :            : }
     315                 :            : 
     316                 :            : static inline bool ip_sk_accept_pmtu(const struct sock *sk)
     317                 :            : {
     318                 :          0 :         return inet_sk(sk)->pmtudisc != IP_PMTUDISC_INTERFACE;
     319                 :            : }
     320                 :            : 
     321                 :            : static inline bool ip_sk_use_pmtu(const struct sock *sk)
     322                 :            : {
     323                 :      54556 :         return inet_sk(sk)->pmtudisc < IP_PMTUDISC_PROBE;
     324                 :            : }
     325                 :            : 
     326                 :          0 : static inline int ip_skb_dst_mtu(const struct sk_buff *skb)
     327                 :            : {
     328 [ #  # ][ #  # ]:     109055 :         return (!skb->sk || ip_sk_use_pmtu(skb->sk)) ?
         [ +  + ][ +  - ]
     329                 :          0 :                dst_mtu(skb_dst(skb)) : skb_dst(skb)->dev->mtu;
     330                 :            : }
     331                 :            : 
     332                 :            : #endif  /* _ROUTE_H */

Generated by: LCOV version 1.9