Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * net/dst.h    Protocol independent destination cache definitions.
0004  *
0005  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
0006  *
0007  */
0008 
0009 #ifndef _NET_DST_H
0010 #define _NET_DST_H
0011 
0012 #include <net/dst_ops.h>
0013 #include <linux/netdevice.h>
0014 #include <linux/rtnetlink.h>
0015 #include <linux/rcupdate.h>
0016 #include <linux/bug.h>
0017 #include <linux/jiffies.h>
0018 #include <linux/refcount.h>
0019 #include <net/neighbour.h>
0020 #include <asm/processor.h>
0021 #include <linux/indirect_call_wrapper.h>
0022 
0023 struct sk_buff;
0024 
0025 struct dst_entry {
0026     struct net_device       *dev;
0027     struct  dst_ops         *ops;
0028     unsigned long       _metrics;
0029     unsigned long           expires;
0030 #ifdef CONFIG_XFRM
0031     struct xfrm_state   *xfrm;
0032 #else
0033     void            *__pad1;
0034 #endif
0035     int         (*input)(struct sk_buff *);
0036     int         (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
0037 
0038     unsigned short      flags;
0039 #define DST_NOXFRM      0x0002
0040 #define DST_NOPOLICY        0x0004
0041 #define DST_NOCOUNT     0x0008
0042 #define DST_FAKE_RTABLE     0x0010
0043 #define DST_XFRM_TUNNEL     0x0020
0044 #define DST_XFRM_QUEUE      0x0040
0045 #define DST_METADATA        0x0080
0046 
0047     /* A non-zero value of dst->obsolete forces by-hand validation
0048      * of the route entry.  Positive values are set by the generic
0049      * dst layer to indicate that the entry has been forcefully
0050      * destroyed.
0051      *
0052      * Negative values are used by the implementation layer code to
0053      * force invocation of the dst_ops->check() method.
0054      */
0055     short           obsolete;
0056 #define DST_OBSOLETE_NONE   0
0057 #define DST_OBSOLETE_DEAD   2
0058 #define DST_OBSOLETE_FORCE_CHK  -1
0059 #define DST_OBSOLETE_KILL   -2
0060     unsigned short      header_len; /* more space at head required */
0061     unsigned short      trailer_len;    /* space to reserve at tail */
0062 
0063     /*
0064      * __refcnt wants to be on a different cache line from
0065      * input/output/ops or performance tanks badly
0066      */
0067 #ifdef CONFIG_64BIT
0068     atomic_t        __refcnt;   /* 64-bit offset 64 */
0069 #endif
0070     int         __use;
0071     unsigned long       lastuse;
0072     struct lwtunnel_state   *lwtstate;
0073     struct rcu_head     rcu_head;
0074     short           error;
0075     short           __pad;
0076     __u32           tclassid;
0077 #ifndef CONFIG_64BIT
0078     atomic_t        __refcnt;   /* 32-bit offset 64 */
0079 #endif
0080     netdevice_tracker   dev_tracker;
0081 };
0082 
0083 struct dst_metrics {
0084     u32     metrics[RTAX_MAX];
0085     refcount_t  refcnt;
0086 } __aligned(4);     /* Low pointer bits contain DST_METRICS_FLAGS */
0087 extern const struct dst_metrics dst_default_metrics;
0088 
0089 u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old);
0090 
0091 #define DST_METRICS_READ_ONLY       0x1UL
0092 #define DST_METRICS_REFCOUNTED      0x2UL
0093 #define DST_METRICS_FLAGS       0x3UL
0094 #define __DST_METRICS_PTR(Y)    \
0095     ((u32 *)((Y) & ~DST_METRICS_FLAGS))
0096 #define DST_METRICS_PTR(X)  __DST_METRICS_PTR((X)->_metrics)
0097 
0098 static inline bool dst_metrics_read_only(const struct dst_entry *dst)
0099 {
0100     return dst->_metrics & DST_METRICS_READ_ONLY;
0101 }
0102 
0103 void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old);
0104 
0105 static inline void dst_destroy_metrics_generic(struct dst_entry *dst)
0106 {
0107     unsigned long val = dst->_metrics;
0108     if (!(val & DST_METRICS_READ_ONLY))
0109         __dst_destroy_metrics_generic(dst, val);
0110 }
0111 
0112 static inline u32 *dst_metrics_write_ptr(struct dst_entry *dst)
0113 {
0114     unsigned long p = dst->_metrics;
0115 
0116     BUG_ON(!p);
0117 
0118     if (p & DST_METRICS_READ_ONLY)
0119         return dst->ops->cow_metrics(dst, p);
0120     return __DST_METRICS_PTR(p);
0121 }
0122 
0123 /* This may only be invoked before the entry has reached global
0124  * visibility.
0125  */
0126 static inline void dst_init_metrics(struct dst_entry *dst,
0127                     const u32 *src_metrics,
0128                     bool read_only)
0129 {
0130     dst->_metrics = ((unsigned long) src_metrics) |
0131         (read_only ? DST_METRICS_READ_ONLY : 0);
0132 }
0133 
0134 static inline void dst_copy_metrics(struct dst_entry *dest, const struct dst_entry *src)
0135 {
0136     u32 *dst_metrics = dst_metrics_write_ptr(dest);
0137 
0138     if (dst_metrics) {
0139         u32 *src_metrics = DST_METRICS_PTR(src);
0140 
0141         memcpy(dst_metrics, src_metrics, RTAX_MAX * sizeof(u32));
0142     }
0143 }
0144 
0145 static inline u32 *dst_metrics_ptr(struct dst_entry *dst)
0146 {
0147     return DST_METRICS_PTR(dst);
0148 }
0149 
0150 static inline u32
0151 dst_metric_raw(const struct dst_entry *dst, const int metric)
0152 {
0153     u32 *p = DST_METRICS_PTR(dst);
0154 
0155     return p[metric-1];
0156 }
0157 
0158 static inline u32
0159 dst_metric(const struct dst_entry *dst, const int metric)
0160 {
0161     WARN_ON_ONCE(metric == RTAX_HOPLIMIT ||
0162              metric == RTAX_ADVMSS ||
0163              metric == RTAX_MTU);
0164     return dst_metric_raw(dst, metric);
0165 }
0166 
0167 static inline u32
0168 dst_metric_advmss(const struct dst_entry *dst)
0169 {
0170     u32 advmss = dst_metric_raw(dst, RTAX_ADVMSS);
0171 
0172     if (!advmss)
0173         advmss = dst->ops->default_advmss(dst);
0174 
0175     return advmss;
0176 }
0177 
0178 static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val)
0179 {
0180     u32 *p = dst_metrics_write_ptr(dst);
0181 
0182     if (p)
0183         p[metric-1] = val;
0184 }
0185 
0186 /* Kernel-internal feature bits that are unallocated in user space. */
0187 #define DST_FEATURE_ECN_CA  (1U << 31)
0188 
0189 #define DST_FEATURE_MASK    (DST_FEATURE_ECN_CA)
0190 #define DST_FEATURE_ECN_MASK    (DST_FEATURE_ECN_CA | RTAX_FEATURE_ECN)
0191 
0192 static inline u32
0193 dst_feature(const struct dst_entry *dst, u32 feature)
0194 {
0195     return dst_metric(dst, RTAX_FEATURES) & feature;
0196 }
0197 
0198 INDIRECT_CALLABLE_DECLARE(unsigned int ip6_mtu(const struct dst_entry *));
0199 INDIRECT_CALLABLE_DECLARE(unsigned int ipv4_mtu(const struct dst_entry *));
0200 static inline u32 dst_mtu(const struct dst_entry *dst)
0201 {
0202     return INDIRECT_CALL_INET(dst->ops->mtu, ip6_mtu, ipv4_mtu, dst);
0203 }
0204 
0205 /* RTT metrics are stored in milliseconds for user ABI, but used as jiffies */
0206 static inline unsigned long dst_metric_rtt(const struct dst_entry *dst, int metric)
0207 {
0208     return msecs_to_jiffies(dst_metric(dst, metric));
0209 }
0210 
0211 static inline u32
0212 dst_allfrag(const struct dst_entry *dst)
0213 {
0214     int ret = dst_feature(dst,  RTAX_FEATURE_ALLFRAG);
0215     return ret;
0216 }
0217 
0218 static inline int
0219 dst_metric_locked(const struct dst_entry *dst, int metric)
0220 {
0221     return dst_metric(dst, RTAX_LOCK) & (1 << metric);
0222 }
0223 
0224 static inline void dst_hold(struct dst_entry *dst)
0225 {
0226     /*
0227      * If your kernel compilation stops here, please check
0228      * the placement of __refcnt in struct dst_entry
0229      */
0230     BUILD_BUG_ON(offsetof(struct dst_entry, __refcnt) & 63);
0231     WARN_ON(atomic_inc_not_zero(&dst->__refcnt) == 0);
0232 }
0233 
0234 static inline void dst_use_noref(struct dst_entry *dst, unsigned long time)
0235 {
0236     if (unlikely(time != dst->lastuse)) {
0237         dst->__use++;
0238         dst->lastuse = time;
0239     }
0240 }
0241 
0242 static inline void dst_hold_and_use(struct dst_entry *dst, unsigned long time)
0243 {
0244     dst_hold(dst);
0245     dst_use_noref(dst, time);
0246 }
0247 
0248 static inline struct dst_entry *dst_clone(struct dst_entry *dst)
0249 {
0250     if (dst)
0251         dst_hold(dst);
0252     return dst;
0253 }
0254 
0255 void dst_release(struct dst_entry *dst);
0256 
0257 void dst_release_immediate(struct dst_entry *dst);
0258 
0259 static inline void refdst_drop(unsigned long refdst)
0260 {
0261     if (!(refdst & SKB_DST_NOREF))
0262         dst_release((struct dst_entry *)(refdst & SKB_DST_PTRMASK));
0263 }
0264 
0265 /**
0266  * skb_dst_drop - drops skb dst
0267  * @skb: buffer
0268  *
0269  * Drops dst reference count if a reference was taken.
0270  */
0271 static inline void skb_dst_drop(struct sk_buff *skb)
0272 {
0273     if (skb->_skb_refdst) {
0274         refdst_drop(skb->_skb_refdst);
0275         skb->_skb_refdst = 0UL;
0276     }
0277 }
0278 
0279 static inline void __skb_dst_copy(struct sk_buff *nskb, unsigned long refdst)
0280 {
0281     nskb->slow_gro |= !!refdst;
0282     nskb->_skb_refdst = refdst;
0283     if (!(nskb->_skb_refdst & SKB_DST_NOREF))
0284         dst_clone(skb_dst(nskb));
0285 }
0286 
0287 static inline void skb_dst_copy(struct sk_buff *nskb, const struct sk_buff *oskb)
0288 {
0289     __skb_dst_copy(nskb, oskb->_skb_refdst);
0290 }
0291 
0292 /**
0293  * dst_hold_safe - Take a reference on a dst if possible
0294  * @dst: pointer to dst entry
0295  *
0296  * This helper returns false if it could not safely
0297  * take a reference on a dst.
0298  */
0299 static inline bool dst_hold_safe(struct dst_entry *dst)
0300 {
0301     return atomic_inc_not_zero(&dst->__refcnt);
0302 }
0303 
0304 /**
0305  * skb_dst_force - makes sure skb dst is refcounted
0306  * @skb: buffer
0307  *
0308  * If dst is not yet refcounted and not destroyed, grab a ref on it.
0309  * Returns true if dst is refcounted.
0310  */
0311 static inline bool skb_dst_force(struct sk_buff *skb)
0312 {
0313     if (skb_dst_is_noref(skb)) {
0314         struct dst_entry *dst = skb_dst(skb);
0315 
0316         WARN_ON(!rcu_read_lock_held());
0317         if (!dst_hold_safe(dst))
0318             dst = NULL;
0319 
0320         skb->_skb_refdst = (unsigned long)dst;
0321         skb->slow_gro |= !!dst;
0322     }
0323 
0324     return skb->_skb_refdst != 0UL;
0325 }
0326 
0327 
0328 /**
0329  *  __skb_tunnel_rx - prepare skb for rx reinsert
0330  *  @skb: buffer
0331  *  @dev: tunnel device
0332  *  @net: netns for packet i/o
0333  *
0334  *  After decapsulation, packet is going to re-enter (netif_rx()) our stack,
0335  *  so make some cleanups. (no accounting done)
0336  */
0337 static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
0338                    struct net *net)
0339 {
0340     skb->dev = dev;
0341 
0342     /*
0343      * Clear hash so that we can recalulate the hash for the
0344      * encapsulated packet, unless we have already determine the hash
0345      * over the L4 4-tuple.
0346      */
0347     skb_clear_hash_if_not_l4(skb);
0348     skb_set_queue_mapping(skb, 0);
0349     skb_scrub_packet(skb, !net_eq(net, dev_net(dev)));
0350 }
0351 
0352 /**
0353  *  skb_tunnel_rx - prepare skb for rx reinsert
0354  *  @skb: buffer
0355  *  @dev: tunnel device
0356  *  @net: netns for packet i/o
0357  *
0358  *  After decapsulation, packet is going to re-enter (netif_rx()) our stack,
0359  *  so make some cleanups, and perform accounting.
0360  *  Note: this accounting is not SMP safe.
0361  */
0362 static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
0363                  struct net *net)
0364 {
0365     /* TODO : stats should be SMP safe */
0366     dev->stats.rx_packets++;
0367     dev->stats.rx_bytes += skb->len;
0368     __skb_tunnel_rx(skb, dev, net);
0369 }
0370 
0371 static inline u32 dst_tclassid(const struct sk_buff *skb)
0372 {
0373 #ifdef CONFIG_IP_ROUTE_CLASSID
0374     const struct dst_entry *dst;
0375 
0376     dst = skb_dst(skb);
0377     if (dst)
0378         return dst->tclassid;
0379 #endif
0380     return 0;
0381 }
0382 
0383 int dst_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb);
0384 static inline int dst_discard(struct sk_buff *skb)
0385 {
0386     return dst_discard_out(&init_net, skb->sk, skb);
0387 }
0388 void *dst_alloc(struct dst_ops *ops, struct net_device *dev, int initial_ref,
0389         int initial_obsolete, unsigned short flags);
0390 void dst_init(struct dst_entry *dst, struct dst_ops *ops,
0391           struct net_device *dev, int initial_ref, int initial_obsolete,
0392           unsigned short flags);
0393 struct dst_entry *dst_destroy(struct dst_entry *dst);
0394 void dst_dev_put(struct dst_entry *dst);
0395 
0396 static inline void dst_confirm(struct dst_entry *dst)
0397 {
0398 }
0399 
0400 static inline struct neighbour *dst_neigh_lookup(const struct dst_entry *dst, const void *daddr)
0401 {
0402     struct neighbour *n = dst->ops->neigh_lookup(dst, NULL, daddr);
0403     return IS_ERR(n) ? NULL : n;
0404 }
0405 
0406 static inline struct neighbour *dst_neigh_lookup_skb(const struct dst_entry *dst,
0407                              struct sk_buff *skb)
0408 {
0409     struct neighbour *n;
0410 
0411     if (WARN_ON_ONCE(!dst->ops->neigh_lookup))
0412         return NULL;
0413 
0414     n = dst->ops->neigh_lookup(dst, skb, NULL);
0415 
0416     return IS_ERR(n) ? NULL : n;
0417 }
0418 
0419 static inline void dst_confirm_neigh(const struct dst_entry *dst,
0420                      const void *daddr)
0421 {
0422     if (dst->ops->confirm_neigh)
0423         dst->ops->confirm_neigh(dst, daddr);
0424 }
0425 
0426 static inline void dst_link_failure(struct sk_buff *skb)
0427 {
0428     struct dst_entry *dst = skb_dst(skb);
0429     if (dst && dst->ops && dst->ops->link_failure)
0430         dst->ops->link_failure(skb);
0431 }
0432 
0433 static inline void dst_set_expires(struct dst_entry *dst, int timeout)
0434 {
0435     unsigned long expires = jiffies + timeout;
0436 
0437     if (expires == 0)
0438         expires = 1;
0439 
0440     if (dst->expires == 0 || time_before(expires, dst->expires))
0441         dst->expires = expires;
0442 }
0443 
0444 INDIRECT_CALLABLE_DECLARE(int ip6_output(struct net *, struct sock *,
0445                      struct sk_buff *));
0446 INDIRECT_CALLABLE_DECLARE(int ip_output(struct net *, struct sock *,
0447                      struct sk_buff *));
0448 /* Output packet to network from transport.  */
0449 static inline int dst_output(struct net *net, struct sock *sk, struct sk_buff *skb)
0450 {
0451     return INDIRECT_CALL_INET(skb_dst(skb)->output,
0452                   ip6_output, ip_output,
0453                   net, sk, skb);
0454 }
0455 
0456 INDIRECT_CALLABLE_DECLARE(int ip6_input(struct sk_buff *));
0457 INDIRECT_CALLABLE_DECLARE(int ip_local_deliver(struct sk_buff *));
0458 /* Input packet from network to transport.  */
0459 static inline int dst_input(struct sk_buff *skb)
0460 {
0461     return INDIRECT_CALL_INET(skb_dst(skb)->input,
0462                   ip6_input, ip_local_deliver, skb);
0463 }
0464 
0465 INDIRECT_CALLABLE_DECLARE(struct dst_entry *ip6_dst_check(struct dst_entry *,
0466                               u32));
0467 INDIRECT_CALLABLE_DECLARE(struct dst_entry *ipv4_dst_check(struct dst_entry *,
0468                                u32));
0469 static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie)
0470 {
0471     if (dst->obsolete)
0472         dst = INDIRECT_CALL_INET(dst->ops->check, ip6_dst_check,
0473                      ipv4_dst_check, dst, cookie);
0474     return dst;
0475 }
0476 
0477 /* Flags for xfrm_lookup flags argument. */
0478 enum {
0479     XFRM_LOOKUP_ICMP = 1 << 0,
0480     XFRM_LOOKUP_QUEUE = 1 << 1,
0481     XFRM_LOOKUP_KEEP_DST_REF = 1 << 2,
0482 };
0483 
0484 struct flowi;
0485 #ifndef CONFIG_XFRM
0486 static inline struct dst_entry *xfrm_lookup(struct net *net,
0487                         struct dst_entry *dst_orig,
0488                         const struct flowi *fl,
0489                         const struct sock *sk,
0490                         int flags)
0491 {
0492     return dst_orig;
0493 }
0494 
0495 static inline struct dst_entry *
0496 xfrm_lookup_with_ifid(struct net *net, struct dst_entry *dst_orig,
0497               const struct flowi *fl, const struct sock *sk,
0498               int flags, u32 if_id)
0499 {
0500     return dst_orig;
0501 }
0502 
0503 static inline struct dst_entry *xfrm_lookup_route(struct net *net,
0504                           struct dst_entry *dst_orig,
0505                           const struct flowi *fl,
0506                           const struct sock *sk,
0507                           int flags)
0508 {
0509     return dst_orig;
0510 }
0511 
0512 static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst)
0513 {
0514     return NULL;
0515 }
0516 
0517 #else
0518 struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
0519                   const struct flowi *fl, const struct sock *sk,
0520                   int flags);
0521 
0522 struct dst_entry *xfrm_lookup_with_ifid(struct net *net,
0523                     struct dst_entry *dst_orig,
0524                     const struct flowi *fl,
0525                     const struct sock *sk, int flags,
0526                     u32 if_id);
0527 
0528 struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig,
0529                     const struct flowi *fl, const struct sock *sk,
0530                     int flags);
0531 
0532 /* skb attached with this dst needs transformation if dst->xfrm is valid */
0533 static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst)
0534 {
0535     return dst->xfrm;
0536 }
0537 #endif
0538 
0539 static inline void skb_dst_update_pmtu(struct sk_buff *skb, u32 mtu)
0540 {
0541     struct dst_entry *dst = skb_dst(skb);
0542 
0543     if (dst && dst->ops->update_pmtu)
0544         dst->ops->update_pmtu(dst, NULL, skb, mtu, true);
0545 }
0546 
0547 /* update dst pmtu but not do neighbor confirm */
0548 static inline void skb_dst_update_pmtu_no_confirm(struct sk_buff *skb, u32 mtu)
0549 {
0550     struct dst_entry *dst = skb_dst(skb);
0551 
0552     if (dst && dst->ops->update_pmtu)
0553         dst->ops->update_pmtu(dst, NULL, skb, mtu, false);
0554 }
0555 
0556 struct dst_entry *dst_blackhole_check(struct dst_entry *dst, u32 cookie);
0557 void dst_blackhole_update_pmtu(struct dst_entry *dst, struct sock *sk,
0558                    struct sk_buff *skb, u32 mtu, bool confirm_neigh);
0559 void dst_blackhole_redirect(struct dst_entry *dst, struct sock *sk,
0560                 struct sk_buff *skb);
0561 u32 *dst_blackhole_cow_metrics(struct dst_entry *dst, unsigned long old);
0562 struct neighbour *dst_blackhole_neigh_lookup(const struct dst_entry *dst,
0563                          struct sk_buff *skb,
0564                          const void *daddr);
0565 unsigned int dst_blackhole_mtu(const struct dst_entry *dst);
0566 
0567 #endif /* _NET_DST_H */