156 lines
4.8 KiB
C
156 lines
4.8 KiB
C
|
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
|
||
|
/* Copyright (c) 2019-2021 Marvell International Ltd. All rights reserved. */
|
||
|
|
||
|
#ifndef _PRESTERA_ROUTER_HW_H_
|
||
|
#define _PRESTERA_ROUTER_HW_H_
|
||
|
|
||
|
struct prestera_vr {
|
||
|
struct list_head router_node;
|
||
|
refcount_t refcount;
|
||
|
u32 tb_id; /* key (kernel fib table id) */
|
||
|
u16 hw_vr_id; /* virtual router ID */
|
||
|
u8 __pad[2];
|
||
|
};
|
||
|
|
||
|
struct prestera_rif_entry {
|
||
|
struct prestera_rif_entry_key {
|
||
|
struct prestera_iface iface;
|
||
|
} key;
|
||
|
struct prestera_vr *vr;
|
||
|
unsigned char addr[ETH_ALEN];
|
||
|
u16 hw_id; /* rif_id */
|
||
|
struct list_head router_node; /* ht */
|
||
|
};
|
||
|
|
||
|
struct prestera_ip_addr {
|
||
|
union {
|
||
|
__be32 ipv4;
|
||
|
struct in6_addr ipv6;
|
||
|
} u;
|
||
|
enum {
|
||
|
PRESTERA_IPV4 = 0,
|
||
|
PRESTERA_IPV6
|
||
|
} v;
|
||
|
#define PRESTERA_IP_ADDR_PLEN(V) ((V) == PRESTERA_IPV4 ? 32 : \
|
||
|
/* (V) == PRESTERA_IPV6 ? */ 128 /* : 0 */)
|
||
|
};
|
||
|
|
||
|
struct prestera_nh_neigh_key {
|
||
|
struct prestera_ip_addr addr;
|
||
|
/* Seems like rif is obsolete, because there is iface in info ?
|
||
|
* Key can contain functional fields, or fields, which is used to
|
||
|
* filter duplicate objects on logical level (before you pass it to
|
||
|
* HW)... also key can be used to cover hardware restrictions.
|
||
|
* In our case rif - is logical interface (even can be VLAN), which
|
||
|
* is used in combination with IP address (which is also not related to
|
||
|
* hardware nexthop) to provide logical compression of created nexthops.
|
||
|
* You even can imagine, that rif+IPaddr is just cookie.
|
||
|
*/
|
||
|
/* struct prestera_rif *rif; */
|
||
|
/* Use just as cookie, to divide ARP domains (in order with addr) */
|
||
|
void *rif;
|
||
|
};
|
||
|
|
||
|
/* Used for hw call */
|
||
|
struct prestera_neigh_info {
|
||
|
struct prestera_iface iface;
|
||
|
unsigned char ha[ETH_ALEN];
|
||
|
u8 connected; /* bool. indicate, if mac/oif valid */
|
||
|
u8 __pad[1];
|
||
|
};
|
||
|
|
||
|
/* Used to notify nh about neigh change */
|
||
|
struct prestera_nh_neigh {
|
||
|
struct prestera_nh_neigh_key key;
|
||
|
struct prestera_neigh_info info;
|
||
|
struct rhash_head ht_node; /* node of prestera_vr */
|
||
|
struct list_head nexthop_group_list;
|
||
|
};
|
||
|
|
||
|
#define PRESTERA_NHGR_SIZE_MAX 4
|
||
|
|
||
|
struct prestera_nexthop_group {
|
||
|
struct prestera_nexthop_group_key {
|
||
|
struct prestera_nh_neigh_key neigh[PRESTERA_NHGR_SIZE_MAX];
|
||
|
} key;
|
||
|
/* Store intermediate object here.
|
||
|
* This prevent overhead kzalloc call.
|
||
|
*/
|
||
|
/* nh_neigh is used only to notify nexthop_group */
|
||
|
struct prestera_nh_neigh_head {
|
||
|
struct prestera_nexthop_group *this;
|
||
|
struct list_head head;
|
||
|
/* ptr to neigh is not necessary.
|
||
|
* It used to prevent lookup of nh_neigh by key (n) on destroy
|
||
|
*/
|
||
|
struct prestera_nh_neigh *neigh;
|
||
|
} nh_neigh_head[PRESTERA_NHGR_SIZE_MAX];
|
||
|
struct rhash_head ht_node; /* node of prestera_vr */
|
||
|
refcount_t refcount;
|
||
|
u32 grp_id; /* hw */
|
||
|
};
|
||
|
|
||
|
struct prestera_fib_key {
|
||
|
struct prestera_ip_addr addr;
|
||
|
u32 prefix_len;
|
||
|
u32 tb_id;
|
||
|
};
|
||
|
|
||
|
struct prestera_fib_info {
|
||
|
struct prestera_vr *vr;
|
||
|
struct list_head vr_node;
|
||
|
enum prestera_fib_type {
|
||
|
PRESTERA_FIB_TYPE_INVALID = 0,
|
||
|
/* must be pointer to nh_grp id */
|
||
|
PRESTERA_FIB_TYPE_UC_NH,
|
||
|
/* It can be connected route
|
||
|
* and will be overlapped with neighbours
|
||
|
*/
|
||
|
PRESTERA_FIB_TYPE_TRAP,
|
||
|
PRESTERA_FIB_TYPE_DROP
|
||
|
} type;
|
||
|
/* Valid only if type = UC_NH*/
|
||
|
struct prestera_nexthop_group *nh_grp;
|
||
|
};
|
||
|
|
||
|
struct prestera_fib_node {
|
||
|
struct rhash_head ht_node; /* node of prestera_vr */
|
||
|
struct prestera_fib_key key;
|
||
|
struct prestera_fib_info info; /* action related info */
|
||
|
};
|
||
|
|
||
|
struct prestera_rif_entry *
|
||
|
prestera_rif_entry_find(const struct prestera_switch *sw,
|
||
|
const struct prestera_rif_entry_key *k);
|
||
|
void prestera_rif_entry_destroy(struct prestera_switch *sw,
|
||
|
struct prestera_rif_entry *e);
|
||
|
struct prestera_rif_entry *
|
||
|
prestera_rif_entry_create(struct prestera_switch *sw,
|
||
|
struct prestera_rif_entry_key *k,
|
||
|
u32 tb_id, const unsigned char *addr);
|
||
|
struct prestera_nh_neigh *
|
||
|
prestera_nh_neigh_find(struct prestera_switch *sw,
|
||
|
struct prestera_nh_neigh_key *key);
|
||
|
struct prestera_nh_neigh *
|
||
|
prestera_nh_neigh_get(struct prestera_switch *sw,
|
||
|
struct prestera_nh_neigh_key *key);
|
||
|
void prestera_nh_neigh_put(struct prestera_switch *sw,
|
||
|
struct prestera_nh_neigh *neigh);
|
||
|
int prestera_nh_neigh_set(struct prestera_switch *sw,
|
||
|
struct prestera_nh_neigh *neigh);
|
||
|
bool prestera_nh_neigh_util_hw_state(struct prestera_switch *sw,
|
||
|
struct prestera_nh_neigh *nh_neigh);
|
||
|
struct prestera_fib_node *prestera_fib_node_find(struct prestera_switch *sw,
|
||
|
struct prestera_fib_key *key);
|
||
|
void prestera_fib_node_destroy(struct prestera_switch *sw,
|
||
|
struct prestera_fib_node *fib_node);
|
||
|
struct prestera_fib_node *
|
||
|
prestera_fib_node_create(struct prestera_switch *sw,
|
||
|
struct prestera_fib_key *key,
|
||
|
enum prestera_fib_type fib_type,
|
||
|
struct prestera_nexthop_group_key *nh_grp_key);
|
||
|
int prestera_router_hw_init(struct prestera_switch *sw);
|
||
|
void prestera_router_hw_fini(struct prestera_switch *sw);
|
||
|
|
||
|
#endif /* _PRESTERA_ROUTER_HW_H_ */
|