linux/include/net/lwtunnel.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef __NET_LWTUNNEL_H
   3#define __NET_LWTUNNEL_H 1
   4
   5#include <linux/lwtunnel.h>
   6#include <linux/netdevice.h>
   7#include <linux/skbuff.h>
   8#include <linux/types.h>
   9#include <net/route.h>
  10
  11#define LWTUNNEL_HASH_BITS   7
  12#define LWTUNNEL_HASH_SIZE   (1 << LWTUNNEL_HASH_BITS)
  13
  14/* lw tunnel state flags */
  15#define LWTUNNEL_STATE_OUTPUT_REDIRECT  BIT(0)
  16#define LWTUNNEL_STATE_INPUT_REDIRECT   BIT(1)
  17#define LWTUNNEL_STATE_XMIT_REDIRECT    BIT(2)
  18
  19enum {
  20        LWTUNNEL_XMIT_DONE,
  21        LWTUNNEL_XMIT_CONTINUE,
  22};
  23
  24
  25struct lwtunnel_state {
  26        __u16           type;
  27        __u16           flags;
  28        __u16           headroom;
  29        atomic_t        refcnt;
  30        int             (*orig_output)(struct net *net, struct sock *sk, struct sk_buff *skb);
  31        int             (*orig_input)(struct sk_buff *);
  32        struct          rcu_head rcu;
  33        __u8            data[0];
  34};
  35
  36struct lwtunnel_encap_ops {
  37        int (*build_state)(struct nlattr *encap,
  38                           unsigned int family, const void *cfg,
  39                           struct lwtunnel_state **ts,
  40                           struct netlink_ext_ack *extack);
  41        void (*destroy_state)(struct lwtunnel_state *lws);
  42        int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
  43        int (*input)(struct sk_buff *skb);
  44        int (*fill_encap)(struct sk_buff *skb,
  45                          struct lwtunnel_state *lwtstate);
  46        int (*get_encap_size)(struct lwtunnel_state *lwtstate);
  47        int (*cmp_encap)(struct lwtunnel_state *a, struct lwtunnel_state *b);
  48        int (*xmit)(struct sk_buff *skb);
  49
  50        struct module *owner;
  51};
  52
  53#ifdef CONFIG_LWTUNNEL
  54void lwtstate_free(struct lwtunnel_state *lws);
  55
  56static inline struct lwtunnel_state *
  57lwtstate_get(struct lwtunnel_state *lws)
  58{
  59        if (lws)
  60                atomic_inc(&lws->refcnt);
  61
  62        return lws;
  63}
  64
  65static inline void lwtstate_put(struct lwtunnel_state *lws)
  66{
  67        if (!lws)
  68                return;
  69
  70        if (atomic_dec_and_test(&lws->refcnt))
  71                lwtstate_free(lws);
  72}
  73
  74static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate)
  75{
  76        if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_OUTPUT_REDIRECT))
  77                return true;
  78
  79        return false;
  80}
  81
  82static inline bool lwtunnel_input_redirect(struct lwtunnel_state *lwtstate)
  83{
  84        if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_INPUT_REDIRECT))
  85                return true;
  86
  87        return false;
  88}
  89
  90static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate)
  91{
  92        if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_XMIT_REDIRECT))
  93                return true;
  94
  95        return false;
  96}
  97
  98static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate,
  99                                             unsigned int mtu)
 100{
 101        if ((lwtunnel_xmit_redirect(lwtstate) ||
 102             lwtunnel_output_redirect(lwtstate)) && lwtstate->headroom < mtu)
 103                return lwtstate->headroom;
 104
 105        return 0;
 106}
 107
 108int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
 109                           unsigned int num);
 110int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
 111                           unsigned int num);
 112int lwtunnel_valid_encap_type(u16 encap_type,
 113                              struct netlink_ext_ack *extack);
 114int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
 115                                   struct netlink_ext_ack *extack);
 116int lwtunnel_build_state(u16 encap_type,
 117                         struct nlattr *encap,
 118                         unsigned int family, const void *cfg,
 119                         struct lwtunnel_state **lws,
 120                         struct netlink_ext_ack *extack);
 121int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate,
 122                        int encap_attr, int encap_type_attr);
 123int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate);
 124struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len);
 125int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b);
 126int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb);
 127int lwtunnel_input(struct sk_buff *skb);
 128int lwtunnel_xmit(struct sk_buff *skb);
 129int bpf_lwt_push_ip_encap(struct sk_buff *skb, void *hdr, u32 len,
 130                          bool ingress);
 131
 132static inline void lwtunnel_set_redirect(struct dst_entry *dst)
 133{
 134        if (lwtunnel_output_redirect(dst->lwtstate)) {
 135                dst->lwtstate->orig_output = dst->output;
 136                dst->output = lwtunnel_output;
 137        }
 138        if (lwtunnel_input_redirect(dst->lwtstate)) {
 139                dst->lwtstate->orig_input = dst->input;
 140                dst->input = lwtunnel_input;
 141        }
 142}
 143#else
 144
 145static inline void lwtstate_free(struct lwtunnel_state *lws)
 146{
 147}
 148
 149static inline struct lwtunnel_state *
 150lwtstate_get(struct lwtunnel_state *lws)
 151{
 152        return lws;
 153}
 154
 155static inline void lwtstate_put(struct lwtunnel_state *lws)
 156{
 157}
 158
 159static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate)
 160{
 161        return false;
 162}
 163
 164static inline bool lwtunnel_input_redirect(struct lwtunnel_state *lwtstate)
 165{
 166        return false;
 167}
 168
 169static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate)
 170{
 171        return false;
 172}
 173
 174static inline void lwtunnel_set_redirect(struct dst_entry *dst)
 175{
 176}
 177
 178static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate,
 179                                             unsigned int mtu)
 180{
 181        return 0;
 182}
 183
 184static inline int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
 185                                         unsigned int num)
 186{
 187        return -EOPNOTSUPP;
 188
 189}
 190
 191static inline int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
 192                                         unsigned int num)
 193{
 194        return -EOPNOTSUPP;
 195}
 196
 197static inline int lwtunnel_valid_encap_type(u16 encap_type,
 198                                            struct netlink_ext_ack *extack)
 199{
 200        NL_SET_ERR_MSG(extack, "CONFIG_LWTUNNEL is not enabled in this kernel");
 201        return -EOPNOTSUPP;
 202}
 203static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
 204                                                 struct netlink_ext_ack *extack)
 205{
 206        /* return 0 since we are not walking attr looking for
 207         * RTA_ENCAP_TYPE attribute on nexthops.
 208         */
 209        return 0;
 210}
 211
 212static inline int lwtunnel_build_state(u16 encap_type,
 213                                       struct nlattr *encap,
 214                                       unsigned int family, const void *cfg,
 215                                       struct lwtunnel_state **lws,
 216                                       struct netlink_ext_ack *extack)
 217{
 218        return -EOPNOTSUPP;
 219}
 220
 221static inline int lwtunnel_fill_encap(struct sk_buff *skb,
 222                                      struct lwtunnel_state *lwtstate,
 223                                      int encap_attr, int encap_type_attr)
 224{
 225        return 0;
 226}
 227
 228static inline int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate)
 229{
 230        return 0;
 231}
 232
 233static inline struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len)
 234{
 235        return NULL;
 236}
 237
 238static inline int lwtunnel_cmp_encap(struct lwtunnel_state *a,
 239                                     struct lwtunnel_state *b)
 240{
 241        return 0;
 242}
 243
 244static inline int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 245{
 246        return -EOPNOTSUPP;
 247}
 248
 249static inline int lwtunnel_input(struct sk_buff *skb)
 250{
 251        return -EOPNOTSUPP;
 252}
 253
 254static inline int lwtunnel_xmit(struct sk_buff *skb)
 255{
 256        return -EOPNOTSUPP;
 257}
 258
 259#endif /* CONFIG_LWTUNNEL */
 260
 261#define MODULE_ALIAS_RTNL_LWT(encap_type) MODULE_ALIAS("rtnl-lwt-" __stringify(encap_type))
 262
 263#endif /* __NET_LWTUNNEL_H */
 264