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[];
  34};
  35
  36struct lwtunnel_encap_ops {
  37        int (*build_state)(struct net *net, 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
  54
  55DECLARE_STATIC_KEY_FALSE(nf_hooks_lwtunnel_enabled);
  56
  57void lwtstate_free(struct lwtunnel_state *lws);
  58
  59static inline struct lwtunnel_state *
  60lwtstate_get(struct lwtunnel_state *lws)
  61{
  62        if (lws)
  63                atomic_inc(&lws->refcnt);
  64
  65        return lws;
  66}
  67
  68static inline void lwtstate_put(struct lwtunnel_state *lws)
  69{
  70        if (!lws)
  71                return;
  72
  73        if (atomic_dec_and_test(&lws->refcnt))
  74                lwtstate_free(lws);
  75}
  76
  77static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate)
  78{
  79        if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_OUTPUT_REDIRECT))
  80                return true;
  81
  82        return false;
  83}
  84
  85static inline bool lwtunnel_input_redirect(struct lwtunnel_state *lwtstate)
  86{
  87        if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_INPUT_REDIRECT))
  88                return true;
  89
  90        return false;
  91}
  92
  93static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate)
  94{
  95        if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_XMIT_REDIRECT))
  96                return true;
  97
  98        return false;
  99}
 100
 101static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate,
 102                                             unsigned int mtu)
 103{
 104        if ((lwtunnel_xmit_redirect(lwtstate) ||
 105             lwtunnel_output_redirect(lwtstate)) && lwtstate->headroom < mtu)
 106                return lwtstate->headroom;
 107
 108        return 0;
 109}
 110
 111int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
 112                           unsigned int num);
 113int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
 114                           unsigned int num);
 115int lwtunnel_valid_encap_type(u16 encap_type,
 116                              struct netlink_ext_ack *extack);
 117int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
 118                                   struct netlink_ext_ack *extack);
 119int lwtunnel_build_state(struct net *net, u16 encap_type,
 120                         struct nlattr *encap,
 121                         unsigned int family, const void *cfg,
 122                         struct lwtunnel_state **lws,
 123                         struct netlink_ext_ack *extack);
 124int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate,
 125                        int encap_attr, int encap_type_attr);
 126int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate);
 127struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len);
 128int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b);
 129int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb);
 130int lwtunnel_input(struct sk_buff *skb);
 131int lwtunnel_xmit(struct sk_buff *skb);
 132int bpf_lwt_push_ip_encap(struct sk_buff *skb, void *hdr, u32 len,
 133                          bool ingress);
 134
 135static inline void lwtunnel_set_redirect(struct dst_entry *dst)
 136{
 137        if (lwtunnel_output_redirect(dst->lwtstate)) {
 138                dst->lwtstate->orig_output = dst->output;
 139                dst->output = lwtunnel_output;
 140        }
 141        if (lwtunnel_input_redirect(dst->lwtstate)) {
 142                dst->lwtstate->orig_input = dst->input;
 143                dst->input = lwtunnel_input;
 144        }
 145}
 146#else
 147
 148static inline void lwtstate_free(struct lwtunnel_state *lws)
 149{
 150}
 151
 152static inline struct lwtunnel_state *
 153lwtstate_get(struct lwtunnel_state *lws)
 154{
 155        return lws;
 156}
 157
 158static inline void lwtstate_put(struct lwtunnel_state *lws)
 159{
 160}
 161
 162static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate)
 163{
 164        return false;
 165}
 166
 167static inline bool lwtunnel_input_redirect(struct lwtunnel_state *lwtstate)
 168{
 169        return false;
 170}
 171
 172static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate)
 173{
 174        return false;
 175}
 176
 177static inline void lwtunnel_set_redirect(struct dst_entry *dst)
 178{
 179}
 180
 181static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate,
 182                                             unsigned int mtu)
 183{
 184        return 0;
 185}
 186
 187static inline int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
 188                                         unsigned int num)
 189{
 190        return -EOPNOTSUPP;
 191
 192}
 193
 194static inline int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
 195                                         unsigned int num)
 196{
 197        return -EOPNOTSUPP;
 198}
 199
 200static inline int lwtunnel_valid_encap_type(u16 encap_type,
 201                                            struct netlink_ext_ack *extack)
 202{
 203        NL_SET_ERR_MSG(extack, "CONFIG_LWTUNNEL is not enabled in this kernel");
 204        return -EOPNOTSUPP;
 205}
 206static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
 207                                                 struct netlink_ext_ack *extack)
 208{
 209        /* return 0 since we are not walking attr looking for
 210         * RTA_ENCAP_TYPE attribute on nexthops.
 211         */
 212        return 0;
 213}
 214
 215static inline int lwtunnel_build_state(struct net *net, u16 encap_type,
 216                                       struct nlattr *encap,
 217                                       unsigned int family, const void *cfg,
 218                                       struct lwtunnel_state **lws,
 219                                       struct netlink_ext_ack *extack)
 220{
 221        return -EOPNOTSUPP;
 222}
 223
 224static inline int lwtunnel_fill_encap(struct sk_buff *skb,
 225                                      struct lwtunnel_state *lwtstate,
 226                                      int encap_attr, int encap_type_attr)
 227{
 228        return 0;
 229}
 230
 231static inline int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate)
 232{
 233        return 0;
 234}
 235
 236static inline struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len)
 237{
 238        return NULL;
 239}
 240
 241static inline int lwtunnel_cmp_encap(struct lwtunnel_state *a,
 242                                     struct lwtunnel_state *b)
 243{
 244        return 0;
 245}
 246
 247static inline int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 248{
 249        return -EOPNOTSUPP;
 250}
 251
 252static inline int lwtunnel_input(struct sk_buff *skb)
 253{
 254        return -EOPNOTSUPP;
 255}
 256
 257static inline int lwtunnel_xmit(struct sk_buff *skb)
 258{
 259        return -EOPNOTSUPP;
 260}
 261
 262#endif /* CONFIG_LWTUNNEL */
 263
 264#define MODULE_ALIAS_RTNL_LWT(encap_type) MODULE_ALIAS("rtnl-lwt-" __stringify(encap_type))
 265
 266#endif /* __NET_LWTUNNEL_H */
 267