1/* 2 * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * 16 * $Id: hndctf.h 408190 2013-06-18 00:32:43Z $ 17 */ 18 19#ifndef _HNDCTF_H_ 20#define _HNDCTF_H_ 21 22#include <bcmutils.h> 23#include <proto/bcmip.h> 24#include <proto/ethernet.h> 25#include <proto/vlan.h> 26 27/* 28 * Define to enable couting VLAN tx and rx packets and bytes. This could be 29 * disabled if the functionality has impact on performance. 30 */ 31#define CTFVLSTATS 32 33#define CTF_ENAB(ci) (((ci) != NULL) && (ci)->_ctf) 34 35#define CTF_ACTION_TAG (1 << 0) 36#define CTF_ACTION_UNTAG (1 << 1) 37#define CTF_ACTION_SNAT (1 << 2) 38#define CTF_ACTION_DNAT (1 << 3) 39#define CTF_ACTION_SUSPEND (1 << 4) 40#define CTF_ACTION_TOS (1 << 5) 41#define CTF_ACTION_MARK (1 << 6) 42#define CTF_ACTION_BYTECNT (1 << 7) 43#define CTF_ACTION_PPPOE_ADD (1 << 8) 44#define CTF_ACTION_PPPOE_DEL (1 << 9) 45 46#define CTF_SUSPEND_TCP (1 << 0) 47#define CTF_SUSPEND_UDP (1 << 1) 48 49#define ctf_attach(osh, n, m, c, a) \ 50 (ctf_attach_fn ? ctf_attach_fn(osh, n, m, c, a) : NULL) 51#define ctf_forward(ci, p, d) (ci)->fn.forward(ci, p, d) 52#define ctf_isenabled(ci, d) (CTF_ENAB(ci) ? (ci)->fn.isenabled(ci, d) : FALSE) 53#define ctf_isbridge(ci, d) (CTF_ENAB(ci) ? (ci)->fn.isbridge(ci, d) : FALSE) 54#define ctf_enable(ci, d, e, b) (CTF_ENAB(ci) ? (ci)->fn.enable(ci, d, e, b) : BCME_OK) 55#define ctf_brc_add(ci, b) (CTF_ENAB(ci) ? (ci)->fn.brc_add(ci, b) : BCME_OK) 56#define ctf_brc_delete(ci, e) (CTF_ENAB(ci) ? (ci)->fn.brc_delete(ci, e) : BCME_OK) 57#define ctf_brc_update(ci, b) (CTF_ENAB(ci) ? (ci)->fn.brc_update(ci, b) : BCME_OK) 58#define ctf_brc_lkup(ci, e) (CTF_ENAB(ci) ? (ci)->fn.brc_lkup(ci, e) : NULL) 59#define ctf_brc_release(ci, b) do { if (CTF_ENAB(ci)) (ci)->fn.brc_release(ci, b); } while (0) 60#define ctf_ipc_add(ci, i, v6) (CTF_ENAB(ci) ? (ci)->fn.ipc_add(ci, i, v6) : BCME_OK) 61#define ctf_ipc_delete(ci, i, v6) \ 62 (CTF_ENAB(ci) ? (ci)->fn.ipc_delete(ci, i, v6) : BCME_OK) 63#define ctf_ipc_count_get(ci, i) \ 64 (CTF_ENAB(ci) ? (ci)->fn.ipc_count_get(ci, i) : BCME_OK) 65#define ctf_ipc_delete_multi(ci, i, im, v6) \ 66 (CTF_ENAB(ci) ? (ci)->fn.ipc_delete_multi(ci, i, im, v6) : BCME_OK) 67#define ctf_ipc_delete_range(ci, s, e, v6) \ 68 (CTF_ENAB(ci) ? (ci)->fn.ipc_delete_range(ci, s, e, v6) : BCME_OK) 69#define ctf_ipc_action(ci, s, e, am, v6) \ 70 (CTF_ENAB(ci) ? (ci)->fn.ipc_action(ci, s, e, am, v6) : BCME_OK) 71#define ctf_ipc_lkup(ci, i, v6) \ 72 (CTF_ENAB(ci) ? (ci)->fn.ipc_lkup(ci, i, v6) : NULL) 73#ifdef CTF_IPV6 74#define ctf_ipc_lkup_l4proto(ci, iph, l4p) (CTF_ENAB(ci) && (ci)->fn.ipc_lkup_l4proto? \ 75 (ci)->fn.ipc_lkup_l4proto((uint8 *)iph, l4p) : NULL) 76#else 77#define ctf_ipc_lkup_l4proto(ci, iph, l4p) (NULL) 78#endif /* CTF_IPV6 */ 79#define ctf_ipc_release(ci, i) do { if (CTF_ENAB(ci)) (ci)->fn.ipc_release(ci, i); } while (0) 80#define ctf_dev_register(ci, d, b) \ 81 (CTF_ENAB(ci) ? (ci)->fn.dev_register(ci, d, b) : BCME_OK) 82#define ctf_dev_vlan_add(ci, d, vid, vd) \ 83 (CTF_ENAB(ci) ? (ci)->fn.dev_vlan_add(ci, d, vid, vd) : BCME_OK) 84#define ctf_dev_vlan_delete(ci, d, vid) \ 85 (CTF_ENAB(ci) ? (ci)->fn.dev_vlan_delete(ci, d, vid) : BCME_OK) 86#define ctf_detach(ci) if (CTF_ENAB(ci)) (ci)->fn.detach(ci) 87#define ctf_dump(ci, b) if (CTF_ENAB(ci)) (ci)->fn.dump(ci, b) 88#define ctf_cfg_req_process(ci, c) if (CTF_ENAB(ci)) (ci)->fn.cfg_req_process(ci, c) 89#define ctf_dev_unregister(ci, d) if (CTF_ENAB(ci)) (ci)->fn.dev_unregister(ci, d) 90 91#define CTFCNTINCR(s) ((s)++) 92#define CTFCNTADD(s, c) ((s) += (c)) 93 94#define PPPOE_ETYPE_OFFSET 12 95#define PPPOE_VER_OFFSET 14 96#define PPPOE_SESID_OFFSET 16 97#define PPPOE_LEN_OFFSET 18 98 99#define PPPOE_HLEN 20 100 101#define PPPOE_PROT_PPP 0x0021 102 103 104typedef struct ctf_pub ctf_t; 105typedef struct ctf_brc ctf_brc_t; 106typedef struct ctf_ipc ctf_ipc_t; 107typedef struct ctf_conn_tuple ctf_conn_tuple_t; 108typedef struct ctf_brc_hot ctf_brc_hot_t; 109 110typedef void (*ctf_detach_cb_t)(ctf_t *ci, void *arg); 111typedef ctf_t * (*ctf_attach_t)(osl_t *osh, uint8 *name, uint32 *msg_level, 112 ctf_detach_cb_t cb, void *arg); 113typedef void (*ctf_detach_t)(ctf_t *ci); 114typedef int32 (*ctf_forward_t)(ctf_t *ci, void *p, void *rxifp); 115typedef bool (*ctf_isenabled_t)(ctf_t *ci, void *dev); 116typedef bool (*ctf_isbridge_t)(ctf_t *ci, void *dev); 117typedef int32 (*ctf_brc_add_t)(ctf_t *ci, ctf_brc_t *brc); 118typedef int32 (*ctf_brc_delete_t)(ctf_t *ci, uint8 *ea); 119typedef int32 (*ctf_brc_update_t)(ctf_t *ci, ctf_brc_t *brc); 120typedef ctf_brc_t * (*ctf_brc_lkup_t)(ctf_t *ci, uint8 *da); 121typedef void (*ctf_brc_release_t)(ctf_t *ci, ctf_brc_t *brc); 122typedef int32 (*ctf_ipc_add_t)(ctf_t *ci, ctf_ipc_t *ipc, bool v6); 123typedef int32 (*ctf_ipc_delete_t)(ctf_t *ci, ctf_ipc_t *ipc, bool v6); 124typedef int32 (*ctf_ipc_count_get_t)(ctf_t *ci); 125typedef int32 (*ctf_ipc_delete_multi_t)(ctf_t *ci, ctf_ipc_t *ipc, 126 ctf_ipc_t *ipcm, bool v6); 127typedef int32 (*ctf_ipc_delete_range_t)(ctf_t *ci, ctf_ipc_t *start, 128 ctf_ipc_t *end, bool v6); 129typedef int32 (*ctf_ipc_action_t)(ctf_t *ci, ctf_ipc_t *start, 130 ctf_ipc_t *end, uint32 action_mask, bool v6); 131typedef ctf_ipc_t * (*ctf_ipc_lkup_t)(ctf_t *ci, ctf_ipc_t *ipc, bool v6); 132typedef uint8 * (*ctf_ipc_lkup_l4proto_t)(uint8 *iph, uint8 *proto_num); 133typedef void (*ctf_ipc_release_t)(ctf_t *ci, ctf_ipc_t *ipc); 134typedef int32 (*ctf_enable_t)(ctf_t *ci, void *dev, bool enable, ctf_brc_hot_t **brc_hot); 135typedef int32 (*ctf_dev_register_t)(ctf_t *ci, void *dev, bool br); 136typedef void (*ctf_dev_unregister_t)(ctf_t *ci, void *dev); 137typedef int32 (*ctf_dev_vlan_add_t)(ctf_t *ci, void *dev, uint16 vid, void *vldev); 138typedef int32 (*ctf_dev_vlan_delete_t)(ctf_t *ci, void *dev, uint16 vid); 139typedef void (*ctf_dump_t)(ctf_t *ci, struct bcmstrbuf *b); 140typedef void (*ctf_cfg_req_process_t)(ctf_t *ci, void *arg); 141 142struct ctf_brc_hot { 143 struct ether_addr ea; /* Dest address */ 144 ctf_brc_t *brcp; /* BRC entry corresp to dest mac */ 145}; 146 147typedef struct ctf_fn { 148 ctf_detach_t detach; 149 ctf_forward_t forward; 150 ctf_isenabled_t isenabled; 151 ctf_isbridge_t isbridge; 152 ctf_brc_add_t brc_add; 153 ctf_brc_delete_t brc_delete; 154 ctf_brc_update_t brc_update; 155 ctf_brc_lkup_t brc_lkup; 156 ctf_brc_release_t brc_release; 157 ctf_ipc_add_t ipc_add; 158 ctf_ipc_delete_t ipc_delete; 159 ctf_ipc_count_get_t ipc_count_get; 160 ctf_ipc_delete_multi_t ipc_delete_multi; 161 ctf_ipc_delete_range_t ipc_delete_range; 162 ctf_ipc_action_t ipc_action; 163 ctf_ipc_lkup_t ipc_lkup; 164 ctf_ipc_lkup_l4proto_t ipc_lkup_l4proto; 165 ctf_ipc_release_t ipc_release; 166 ctf_enable_t enable; 167 ctf_dev_register_t dev_register; 168 ctf_dev_unregister_t dev_unregister; 169 ctf_detach_cb_t detach_cb; 170 void *detach_cb_arg; 171 ctf_dev_vlan_add_t dev_vlan_add; 172 ctf_dev_vlan_delete_t dev_vlan_delete; 173 ctf_dump_t dump; 174 ctf_cfg_req_process_t cfg_req_process; 175} ctf_fn_t; 176 177struct ctf_pub { 178 bool _ctf; /* Global CTF enable/disable */ 179 ctf_fn_t fn; /* Exported functions */ 180 void *nl_sk; /* Netlink socket */ 181 uint32 ipc_suspend; /* Global IPC suspend flags */ 182}; 183 184struct ctf_mark; /* Connection Mark */ 185 186struct ctf_brc { 187 struct ctf_brc *next; /* Pointer to brc entry */ 188 struct ether_addr dhost; /* MAC addr of host */ 189 uint16 vid; /* VLAN id to use on txif */ 190 void *txifp; /* Interface connected to host */ 191 uint32 action; /* Tag or untag the frames */ 192 uint32 live; /* Counter used to expire the entry */ 193 uint32 hits; /* Num frames matching brc entry */ 194 uint64 *bytecnt_ptr; /* Pointer to the byte counter */ 195}; 196 197#ifdef CTF_IPV6 198#define IPADDR_U32_SZ (IPV6_ADDR_LEN / sizeof(uint32)) 199#else 200#define IPADDR_U32_SZ 1 201#endif 202 203struct ctf_conn_tuple { 204 uint32 sip[IPADDR_U32_SZ], dip[IPADDR_U32_SZ]; 205 uint16 sp, dp; 206 uint8 proto; 207}; 208 209typedef struct ctf_nat { 210 uint32 ip; 211 uint16 port; 212} ctf_nat_t; 213 214struct ctf_ipc { 215 struct ctf_ipc *next; /* Pointer to ipc entry */ 216 ctf_conn_tuple_t tuple; /* Tuple to uniquely id the flow */ 217 uint16 vid; /* VLAN id to use on txif */ 218 struct ether_addr dhost; /* Destination MAC address */ 219 struct ether_addr shost; /* Source MAC address */ 220 void *txif; /* Target interface to send */ 221 uint32 action; /* NAT and/or VLAN actions */ 222 ctf_brc_t *brcp; /* BRC entry corresp to source mac */ 223 uint32 live; /* Counter used to expire the entry */ 224 struct ctf_nat nat; /* Manip data for SNAT, DNAT */ 225 struct ether_addr sa; /* MAC address of sender */ 226 uint8 tos; /* IPv4 tos or IPv6 traff class excl ECN */ 227 uint16 pppoe_sid; /* PPPOE session to use */ 228 void *ppp_ifp; /* PPP interface handle */ 229 uint32 hits; /* Num frames matching ipc entry */ 230 uint64 *bytecnt_ptr; /* Pointer to the byte counter */ 231 struct ctf_mark mark; /* Mark value to use for the connection */ 232}; 233 234extern ctf_t *ctf_kattach(osl_t *osh, uint8 *name); 235extern void ctf_kdetach(ctf_t *kci); 236extern ctf_attach_t ctf_attach_fn; 237extern ctf_t *_ctf_attach(osl_t *osh, uint8 *name, uint32 *msg_level, 238 ctf_detach_cb_t cb, void *arg); 239extern ctf_t *kcih; 240 241/* Hot bridge cache lkup */ 242#define MAXBRCHOT 4 243#define MAXBRCHOTIF 4 244#define CTF_BRC_HOT_HASH(da) ((((uint8 *)da)[4] ^ ((uint8 *)da)[5]) & (MAXBRCHOT - 1)) 245#define CTF_HOTBRC_CMP(hbrc, da, rxifp) \ 246({ \ 247 ctf_brc_hot_t *bh = (hbrc) + CTF_BRC_HOT_HASH(da); \ 248 ((eacmp((bh)->ea.octet, (da)) == 0) && (bh->brcp->txifp != (rxifp))); \ 249}) 250 251/* Header prep for packets matching hot bridge cache entry */ 252#define CTF_HOTBRC_L2HDR_PREP(osh, hbrc, prio, data, p) \ 253do { \ 254 uint8 *l2h; \ 255 ctf_brc_hot_t *bh = (hbrc) + CTF_BRC_HOT_HASH(data); \ 256 ASSERT(*(uint16 *)((data) + VLAN_TPID_OFFSET) == HTON16(ETHER_TYPE_8021Q)); \ 257 if (bh->brcp->action & CTF_ACTION_UNTAG) { \ 258 /* Remove vlan header */ \ 259 l2h = PKTPULL((osh), (p), VLAN_TAG_LEN); \ 260 ether_rcopy(l2h - VLAN_TAG_LEN + ETHER_ADDR_LEN, \ 261 l2h + ETHER_ADDR_LEN); \ 262 ether_rcopy(l2h - VLAN_TAG_LEN, l2h); \ 263 } else { \ 264 /* Update vlan header */ \ 265 l2h = (data); \ 266 *(uint16 *)(l2h + VLAN_TCI_OFFSET) = \ 267 HTON16((prio) << VLAN_PRI_SHIFT | bh->brcp->vid); \ 268 } \ 269} while (0) 270 271 272#endif /* _HNDCTF_H_ */ 273