diff --git a/include/linux/bcm_br_fdb.h b/include/linux/bcm_br_fdb.h new file mode 100644 index 0000000000000000000000000000000000000000..3a86253a753d6196d4507f40daef97aa752ac98c --- /dev/null +++ b/include/linux/bcm_br_fdb.h @@ -0,0 +1,48 @@ +#ifndef _BCM_BR_FDB_H +#define _BCM_BR_FDB_H +/* +<:copyright-BRCM:2013:DUAL/GPL:standard + + Copyright (c) 2013 Broadcom + All Rights Reserved + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + +int bcm_br_has_fdb_expired(const struct net_bridge *br, + const struct net_bridge_fdb_entry *fdb); + +int bcm_br_fdb_notify(struct net_bridge *br, + const struct net_bridge_fdb_entry *fdb, int type, + bool swdev_notify); + +int bcm_br_fdb_init(struct net_bridge_fdb_entry *fdb); + +int bcm_br_fdb_fill_info(const struct net_bridge_fdb_entry *fdb); + +int bcm_br_fdb_update(struct net_bridge_fdb_entry *fdb, + struct net_bridge_port *source); + +int bcm_br_fdb_cleanup(struct net_bridge_fdb_entry *fdb, + unsigned long time_now, unsigned long delay); +#endif diff --git a/include/linux/bcm_br_mcast.h b/include/linux/bcm_br_mcast.h new file mode 100644 index 0000000000000000000000000000000000000000..4ef3146d6bb3a0fe9f21a0113fa56cabb52f79dd --- /dev/null +++ b/include/linux/bcm_br_mcast.h @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2003-2019 Broadcom +* All Rights Reserved +* +<:label-BRCM:2019:DUAL/GPL:standard + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ +#if (defined(CONFIG_BCM_MCAST) || defined(CONFIG_BCM_MCAST_MODULE)) + +#ifndef _BCM_BR_MCAST_H +#define _BCM_BR_MCAST_H + +#include <linux/skbuff.h> +#include <linux/netdevice.h> + +typedef int (*br_bcm_mcast_receive_hook)(int ifindex, struct sk_buff *skb, int is_routed); +typedef int (*br_bcm_mcast_should_deliver_hook)(int ifindex, struct sk_buff *skb, struct net_device *src_dev, bool dst_mrouter); + +int br_bcm_mcast_flood_forward(struct net_device *dev, struct sk_buff *skb); +int br_bcm_mcast_bind(br_bcm_mcast_receive_hook bcm_rx_hook, br_bcm_mcast_should_deliver_hook bcm_should_deliver_hook); + +#endif /* _BCM_BR_MCAST_H */ +#endif diff --git a/include/linux/bcm_dslcpe_wlan_info.h b/include/linux/bcm_dslcpe_wlan_info.h new file mode 100755 index 0000000000000000000000000000000000000000..f14fc33aaae8411b854c2864ed1c84a2d73c0df4 --- /dev/null +++ b/include/linux/bcm_dslcpe_wlan_info.h @@ -0,0 +1,27 @@ +#ifndef __BCM_DSLCPE_WLAN_INFO_H_ +#define __BCM_DSLCPE_WLAN_INFO_H_ +#if defined(CONFIG_BLOG) +#include <linux/blog.h> +#define WLAN_CLIENT_INFO_OK (0) +#define WLAN_CLIENT_INFO_ERR (-1) +typedef enum { + WLAN_CLIENT_TYPE_CPU, + WLAN_CLIENT_TYPE_WFD, + WLAN_CLIENT_TYPE_RUNNER, + WLAN_CLIENT_TYPE_MAX +} wlan_client_type_t; + +typedef struct { + wlan_client_type_t type; + union { + uint32_t wl; + BlogWfd_t wfd; + BlogRnr_t rnr; + }; +} wlan_client_info_t; + + +typedef int (* wlan_client_get_info_t)(struct net_device *dev,char *mac_address_p,int priority, wlan_client_info_t *info_p); + +#endif /* CONFIG_BLOG */ +#endif /* __BCM_DSLCPE_WLAN_INFO_H_ */ diff --git a/include/linux/bcm_log.h b/include/linux/bcm_log.h new file mode 100644 index 0000000000000000000000000000000000000000..193376e46c2c0906fcda42dcd3352df918518b52 --- /dev/null +++ b/include/linux/bcm_log.h @@ -0,0 +1,313 @@ +/* +* <:copyright-BRCM:2012:DUAL/GPL:standard +* +* Copyright (c) 2012 Broadcom +* All Rights Reserved +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed +* to you under the terms of the GNU General Public License version 2 +* (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +* with the following added to such license: +* +* As a special exception, the copyright holders of this software give +* you permission to link this software with independent modules, and +* to copy and distribute the resulting executable under terms of your +* choice, provided that you also meet, for each linked independent +* module, the terms and conditions of the license of that module. +* An independent module is a module which is not derived from this +* software. The special exception does not apply to any modifications +* of the software. +* +* Not withstanding the above, under no circumstances may you combine +* this software in any way with any other Broadcom software provided +* under a license other than the GPL, without Broadcom's express prior +* written consent. +* +:> +*/ +#ifndef _BCM_LOG_SERVICES_ +#define _BCM_LOG_SERVICES_ + +#if !defined(__KERNEL__) +#include <stdint.h> /**< ISO C99 7.18 Integer Types */ +#include <stdio.h> +#include <string.h> +#endif + +#include <linux/bcm_log_mod.h> + +#if !defined(__KERNEL__) +#define bcm_printk printf +#define BUG() do { } while(0) +#define EXPORT_SYMBOL(sym) +#endif + +/********* + ********* + * Private: + ********* + *********/ + + +#define IN /*Input parameters*/ +#define OUT /*Output parameters*/ +#define INOUT /*Input/Output parameters*/ + +/* + * This block of defines selects supported functionality for everything + * that includes bcm_log.h. Selection of functionality will eventually + * be moved to make menuconfig. CONFIG_BRCM_COLORIZE_PRINTS is already + * in make menuconfig, but it is locally disabled here. + */ +#ifdef CONFIG_BCM_LOG +#undef CONFIG_BRCM_COLORIZE_PRINTS +#define BCM_ASSERT_SUPPORTED +#define BCM_LOG_SUPPORTED +#define BCM_DATADUMP_SUPPORTED +#define BCM_ERROR_SUPPORTED +#undef BCM_SNAPSHOT_SUPPORTED +#endif /* CONFIG_BCM_LOG */ + +#include <linux/bcm_colors.h> + +#if defined(BCM_ASSERT_SUPPORTED) +#define BCM_ASSERTCODE(code) code +#else +#define BCM_ASSERTCODE(code) +#endif /*defined(BCM_ASSERT_SUPPORTED)*/ + +#if defined(BCM_LOG_SUPPORTED) +#define BCM_LOGCODE(code) code +#else +#define BCM_LOGCODE(code) +#endif /*defined(BCM_LOG_SUPPORTED)*/ + +#if defined(BCM_ERROR_SUPPORTED) +#define BCM_ERRORCODE(code) code +#else +#define BCM_ERRORCODE(code) +#endif /*defined(BCM_ERROR_SUPPORTED)*/ + +#if defined(BCM_DATADUMP_SUPPORTED) +#define BCM_DATADUMPCODE(code) code +#else +#define BCM_DATADUMPCODE(code) +#endif /*defined(BCM_DATADUMP_SUPPORTED)*/ + +#if defined(BCM_SNAPSHOT_SUPPORTED) +#define BCM_SNAPSHOTCODE(code) code +#else +#define BCM_SNAPSHOTCODE(code) +#endif /*defined(BCM_SNAPSHOT_SUPPORTED)*/ + +typedef enum { + BCM_LOG_DD_IMPORTANT=0, + BCM_LOG_DD_INFO, + BCM_LOG_DD_DETAIL, + BCM_LOG_DD_MAX +} bcmLogDataDumpLevel_t; + +typedef void (*bcmLogLevelChangeCallback_t)(bcmLogId_t logId, bcmLogLevel_t level, void *ctx); + +typedef struct { + bcmLogId_t logId; + char *name; + bcmLogLevel_t logLevel; + bcmLogDataDumpLevel_t ddLevel; + bcmLogLevelChangeCallback_t lcCallback; + void * lcCallbackCtx; +} bcmLogModuleInfo_t; + + +/******** + ******** + * Public: service API offered by LOGdriver to other drivers + ******** + ********/ +#if defined(__KERNEL__) +/* This fucntion is same as printk, but is defined always + * and should be used in binary only modules to avoid + * dependency on CONFIG_PRINTK. It can be used in place of + * regular printk as well. + * + * All driver should use/define macro based on this function and + * should not create new clones. + */ +int bcm_printk(const char *fmt, ...); +#define bcm_pr_cont(fmt, ...) bcm_printk(KERN_CONT fmt, ##__VA_ARGS__) +#define bcm_print(fmt, ...) bcm_pr_cont(fmt, ##__VA_ARGS__) +#define bcm_pr_hex_dump_offset(r, g, b, l, a) \ + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, r, g, b, l, a) +#endif + +/** + * Logging API: Activate by #defining BCM_LOG_SUPPORTED + **/ + +#if defined(BCM_LOG_SUPPORTED) +bcmLogModuleInfo_t *bcmLog_logIsEnabled(bcmLogId_t logId, bcmLogLevel_t logLevel); +#endif + +#define BCM_LOG_FUNC(logId) \ + BCM_LOG_DEBUG((logId), " ") + +#define BCM_LOG_DEBUG(logId, fmt, arg...) \ + BCM_LOGCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_logIsEnabled(logId, BCM_LOG_LEVEL_DEBUG); \ + if (_pModInfo) \ + bcm_printk(CLRm "[DBG " "%s" "] %-10s: " fmt CLRnl, \ + _pModInfo->name, __FUNCTION__, ##arg); } while(0) ) + +#define BCM_LOG_INFO(logId, fmt, arg...) \ + BCM_LOGCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_logIsEnabled(logId, BCM_LOG_LEVEL_INFO); \ + if (_pModInfo) \ + bcm_printk(CLRg "[INF " "%s" "] %-10s: " fmt CLRnl, \ + _pModInfo->name, __FUNCTION__, ##arg); } while(0) ) + +#define BCM_LOG_NOTICE(logId, fmt, arg...) \ + BCM_LOGCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_logIsEnabled(logId, BCM_LOG_LEVEL_NOTICE); \ + if (_pModInfo) \ + bcm_printk(CLRb "[NTC " "%s" "] %-10s: " fmt CLRnl, \ + _pModInfo->name, __FUNCTION__, ##arg); } while(0) ) + + +/** + * Error Reporting API: Activate by #defining BCM_ERROR_SUPPORTED + **/ + +#define BCM_LOG_ERROR(logId, fmt, arg...) \ + BCM_ERRORCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_logIsEnabled(logId, BCM_LOG_LEVEL_ERROR); \ + if (_pModInfo) \ + bcm_printk(CLRerr "[ERROR " "%s" "] %-10s,%d: " fmt CLRnl, \ + _pModInfo->name, __FUNCTION__, __LINE__, ##arg); } while(0) ) + + +/** + * Assert API: Activate by #defining BCM_ASSERT_SUPPORTED + **/ + +#define BCM_ASSERT(cond) \ + BCM_ASSERTCODE( if ( !(cond) ) { \ + bcm_printk(CLRerr "[ASSERT " "%s" "] %-10s,%d: " #cond CLRnl, \ + __FILE__, __FUNCTION__, __LINE__); \ + BUG(); \ + } ) + + +/** + * Datadump API: Activate by #defining BCM_DATADUMP_SUPPORTED + **/ + +/* + * Prototype of datadump print functions. + * Note: parse functions must be exported (EXPORT_SYMBOL) + */ +typedef int (Bcm_DataDumpPrintFunc)(uint32_t dataDumpId, IN void* dataPtr, uint32_t numDataBytes, + OUT char* buf, uint32_t bufSize); + +#if defined(BCM_DATADUMP_SUPPORTED) +bcmLogModuleInfo_t *bcmLog_ddIsEnabled(bcmLogId_t logId, bcmLogDataDumpLevel_t ddLevel); +void bcm_dataDumpRegPrinter(uint32_t qId, uint32_t dataDumpId, Bcm_DataDumpPrintFunc *printFun); +void bcm_dataDump(uint32_t qID, uint32_t dataDumpID, const char* dataDumpName, void *ptr, uint32_t numBytes); +uint32_t bcm_dataDumpCreateQ(const char* qName); +void bcm_dataDumpDeleteQ(uint32_t qid); +#endif + +/* + * Create a DataDump queue. Different modules can share a queue. + * Returns a queue ID (uint32_t). + */ +#define BCM_DATADUMP_CREATE_Q(qName) BCM_DATADUMPCODE(bcm_dataDumpCreateQ(qName)) + +/* + * Delete a DataDump queue. + */ +#define BCM_DATADUMP_DELETE_Q(qID) BCM_DATADUMPCODE(bcm_dataDumpDeleteQ(qID)) + +/* + * Dump data + */ +#define BCM_DATADUMP_IMPORTANT(logId, qID, dataDumpID, ptr, numBytes) \ + BCM_DATADUMPCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_ddIsEnabled(logId, BCM_LOG_DD_IMPORTANT); \ + if (_pModInfo) \ + bcm_dataDump(qID, dataDumpID, #dataDumpID, (void*)(ptr), numBytes); } while(0) ) +#define BCM_DATADUMP_INFO(logId, qID, dataDumpID, ptr, numBytes) \ + BCM_DATADUMPCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_ddIsEnabled(logId, BCM_LOG_DD_INFO); \ + if (_pModInfo) \ + bcm_dataDump(qID, dataDumpID, #dataDumpID, (void*)(ptr), numBytes); } while(0) ) +#define BCM_DATADUMP_DETAIL(logId, qID, dataDumpID, ptr, numBytes) \ + BCM_DATADUMPCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_ddIsEnabled(logId, BCM_LOG_DD_DETAIL); \ + if (_pModInfo) \ + bcm_dataDump(qID, dataDumpID, #dataDumpID, (void*)(ptr), numBytes); } while(0) ) +#define BCM_DATADUMP_MAX(logId, qID, dataDumpID, ptr, numBytes) \ + BCM_DATADUMPCODE( do { bcmLogModuleInfo_t *_pModInfo = bcmLog_ddIsEnabled(logId, BCM_LOG_DD_MAX); \ + if (_pModInfo) \ + bcm_dataDump(qID, dataDumpID, #dataDumpID, (void*)(ptr), numBytes); } while(0) ) + +/* + * Register a printer for a certain DataDump ID. + * Datadumps for which no printer is registered will use a default printer. + * The default printer will print the data as an array of bytes. + */ +#define BCM_DATADUMP_REG_PRINTER(qId, dataDumpId, printFun) \ + BCM_DATADUMPCODE(bcm_dataDumpRegPrinter(qId, dataDumpId, printFun)) + +/* A helper macro for datadump printers */ +#define DDPRINTF(buf, len, bufSize, arg...) \ + ({len += snprintf((buf)+(len), max_t(uint32_t, 0, (bufSize)-80-(len)), ##arg); \ + if ((len) >= (bufSize)-80) snprintf((buf)+(len), 80, "---BUFFER FULL---\n");}) + + +/** + * Snapshot API: Commit all logs to the Snapshot queue + **/ + +#define BCM_LOG_SNAPSHOT() BCM_SNAPSHOTCODE() /*TBD*/ + + +/** + * API Function Prototypes + **/ + +#ifdef CONFIG_BCM_LOG + +void bcmLog_setGlobalLogLevel(bcmLogLevel_t logLevel); +bcmLogLevel_t bcmLog_getGlobalLogLevel(void); + +void bcmLog_setLogLevel(bcmLogId_t logId, bcmLogLevel_t logLevel); +bcmLogLevel_t bcmLog_getLogLevel(bcmLogId_t logId); + +char *bcmLog_getModName(bcmLogId_t logId); + +typedef int (bcmFun_t)(void *); + +/*Register a function with the bcmLog driver*/ +void bcmFun_reg(bcmFunId_t funId, bcmFun_t *f); + +/*De-Register a function with the bcmLog driver*/ +void bcmFun_dereg(bcmFunId_t funId); + +/*Look up a function by FunId. Returns NULL if the function is not + *registered.*/ +bcmFun_t* bcmFun_get(bcmFunId_t funId); + +void bcmLog_registerLevelChangeCallback(bcmLogId_t logId, bcmLogLevelChangeCallback_t callback, void *ctx); + +#else + +/* BCM LOG not configured: create empty stubs for all functions */ +static inline bcmLogModuleInfo_t *bcmLog_logIsEnabled(bcmLogId_t logId, bcmLogLevel_t logLevel) { return NULL; } +static inline void bcmLog_setGlobalLogLevel(bcmLogLevel_t loglevel) {} +static inline bcmLogLevel_t bcmLog_getGlobalLogLevel(void) { return 0; } +static inline char *bcmLog_getModName(bcmLogId_t logId) { return NULL; } +static inline void bcmLog_setLogLevel(bcmLogId_t logId, bcmLogLevel_t logLevel) {} +static inline bcmLogLevel_t bcmLog_getLogLevel(bcmLogId_t logId) { return 0; } +typedef int (bcmFun_t)(void *); +static inline void bcmFun_reg(bcmFunId_t funId, bcmFun_t f) {} +static inline void bcmFun_dereg(bcmFunId_t funId) {} +static inline bcmFun_t* bcmFun_get(bcmFunId_t funId) { return NULL; } +static inline void bcmLog_registerLevelChangeCallback(bcmLogId_t logId, bcmLogLevelChangeCallback_t callback, void *ctx) {} + + +#endif /* CONFIG_BCM_LOG */ +#endif /*_BCM_LOG_SERVICES_*/ diff --git a/include/linux/bcm_log_mod.h b/include/linux/bcm_log_mod.h new file mode 100644 index 0000000000000000000000000000000000000000..1a7ff82d9c45791319e6482a1ae56d791cc95abd --- /dev/null +++ b/include/linux/bcm_log_mod.h @@ -0,0 +1,313 @@ +/* +* <:copyright-BRCM:2010:DUAL/GPL:standard +* +* Copyright (c) 2010 Broadcom +* All Rights Reserved +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed +* to you under the terms of the GNU General Public License version 2 +* (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +* with the following added to such license: +* +* As a special exception, the copyright holders of this software give +* you permission to link this software with independent modules, and +* to copy and distribute the resulting executable under terms of your +* choice, provided that you also meet, for each linked independent +* module, the terms and conditions of the license of that module. +* An independent module is a module which is not derived from this +* software. The special exception does not apply to any modifications +* of the software. +* +* Not withstanding the above, under no circumstances may you combine +* this software in any way with any other Broadcom software provided +* under a license other than the GPL, without Broadcom's express prior +* written consent. +* +* :> + +*/ + +#ifndef _BCM_LOG_MODULES_ +#define _BCM_LOG_MODULES_ + +typedef enum { + BCM_LOG_LEVEL_ERROR=0, + BCM_LOG_LEVEL_NOTICE, + BCM_LOG_LEVEL_INFO, + BCM_LOG_LEVEL_DEBUG, + BCM_LOG_LEVEL_MAX +} bcmLogLevel_t; + +/* To support a new module, create a new log ID in bcmLogId_t, + and a new entry in BCM_LOG_MODULE_INFO */ + + +typedef enum { + BCM_LOG_ID_LOG=0, + BCM_LOG_ID_VLAN, + BCM_LOG_ID_GPON, + BCM_LOG_ID_PLOAM, + BCM_LOG_ID_PLOAM_FSM, + BCM_LOG_ID_PLOAM_HAL, + BCM_LOG_ID_PLOAM_PORT, + BCM_LOG_ID_PLOAM_ALARM, + BCM_LOG_ID_OMCI, + BCM_LOG_ID_I2C, + BCM_LOG_ID_ENET, + BCM_LOG_ID_GPON_SERDES, + BCM_LOG_ID_AE, + BCM_LOG_ID_XTM, + BCM_LOG_ID_IQ, + BCM_LOG_ID_BPM, + BCM_LOG_ID_ARL, + BCM_LOG_ID_EPON, + BCM_LOG_ID_GMAC, + BCM_LOG_ID_RDPA, + BCM_LOG_ID_RDPA_CMD_DRV, + BCM_LOG_ID_PKTRUNNER, + BCM_LOG_ID_SIM_CARD, + BCM_LOG_ID_PMD, + BCM_LOG_ID_TM, + BCM_LOG_ID_SPDSVC, + BCM_LOG_ID_MCAST, + BCM_LOG_ID_DPI, + BCM_LOG_ID_CMDLIST, + BCM_LOG_ID_ARCHER, + BCM_LOG_ID_TOD, + BCM_LOG_ID_PON_PWM, + BCM_LOG_ID_OPTICALDET, + BCM_LOG_ID_WANTYPEDET, + BCM_LOG_ID_XPORT, + BCM_LOG_ID_BCMLIBS_BIT_POOL, + BCM_LOG_ID_MPM, + BCM_LOG_ID_MAX +} bcmLogId_t; + +#define BCM_LOG_MODULE_INFO \ + { \ + {.logId = BCM_LOG_ID_LOG, .name = "bcmlog", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_VLAN, .name = "vlan", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_GPON, .name = "gpon", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_PLOAM, .name = "ploam", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_PLOAM_FSM, .name = "ploamFsm", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_PLOAM_HAL, .name = "ploamHal", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_PLOAM_PORT, .name = "ploamPort", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_PLOAM_ALARM, .name = "ploamAlarm", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_OMCI, .name = "omci", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_I2C, .name = "i2c", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_ENET, .name = "enet", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_GPON_SERDES, .name = "gponSerdes", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_AE, .name = "ae", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_XTM, .name = "xtm", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_IQ, .name = "iq", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_BPM, .name = "bpm", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_ARL, .name = "arl", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_EPON, .name = "eponlue", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_GMAC, .name = "gmac", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_RDPA, .name = "rdpa", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_RDPA_CMD_DRV, .name = "rdpadrv", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_PKTRUNNER, .name = "pktrunner", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_SIM_CARD, .name = "sim_card", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_PMD, .name = "pmd", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_TM, .name = "tm", .logLevel = BCM_LOG_LEVEL_ERROR}, \ + {.logId = BCM_LOG_ID_SPDSVC, .name = "spdsvc", .logLevel = BCM_LOG_LEVEL_ERROR}, \ + {.logId = BCM_LOG_ID_MCAST, .name = "mcast", .logLevel = BCM_LOG_LEVEL_ERROR}, \ + {.logId = BCM_LOG_ID_DPI, .name = "dpi", .logLevel = BCM_LOG_LEVEL_ERROR}, \ + {.logId = BCM_LOG_ID_CMDLIST, .name = "cmdlist", .logLevel = BCM_LOG_LEVEL_ERROR}, \ + {.logId = BCM_LOG_ID_ARCHER, .name = "archer", .logLevel = BCM_LOG_LEVEL_ERROR}, \ + {.logId = BCM_LOG_ID_TOD, .name = "tod", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_PON_PWM, .name = "pon_pwm", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_OPTICALDET, .name = "opticaldet", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_WANTYPEDET, .name = "wantypedet", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_XPORT, .name = "xport", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_BCMLIBS_BIT_POOL, .name = "bitpool", .logLevel = BCM_LOG_LEVEL_NOTICE}, \ + {.logId = BCM_LOG_ID_MPM, .name = "mpm", .logLevel = BCM_LOG_LEVEL_ERROR}, \ + } + +/* To support a new registered function, + * create a new BCM_FUN_ID */ + +typedef enum { + BCM_FUN_ID_RESET_SWITCH=0, + BCM_FUN_ID_ENET_LINK_CHG, + BCM_FUN_ID_ENET_CHECK_SWITCH_LOCKUP, + BCM_FUN_ID_ENET_GET_PORT_BUF_USAGE, + BCM_FUN_ID_GPON_GET_GEM_PID_QUEUE, + BCM_FUN_ID_ENET_HANDLE, + BCM_FUN_ID_EPON_HANDLE, + BCM_FUN_IN_ENET_CLEAR_ARL_ENTRY, + BCM_FUN_ID_ENET_IS_WAN_PORT, /* Take Logical port number as argument */ + BCM_FUN_ID_ENET_IS_SWSWITCH_PORT, + BCM_FUN_ID_ENET_LAG_PORT_GET, + BCM_FUN_ID_ENET_PORT_ROLE_NOTIFY, + BCM_FUN_ID_ENET_BOND_RX_PORT_MAP, + BCM_FUN_ID_ENET_SYSPORT_CONFIG, + BCM_FUN_ID_ENET_SYSPORT_QUEUE_MAP, + BCM_FUN_ID_ENET_REMAP_TX_QUEUE, + BCM_FUN_ID_ENET_PHY_SPEED_SET, + BCM_FUN_ID_ENET_TM_EN_SET, + /* The arguments of the BCM TM functions are defined by bcmTmDrv_arg_t */ + BCM_FUN_ID_TM_REGISTER, + BCM_FUN_ID_TM_PORT_CONFIG, + BCM_FUN_ID_TM_PORT_ENABLE, + BCM_FUN_ID_TM_ARBITER_CONFIG, + BCM_FUN_ID_TM_QUEUE_CONFIG, + BCM_FUN_ID_TM_APPLY, + BCM_FUN_ID_TM_ENQUEUE, + /* The arguments of the Speed Service functions are defined in spdsvc_defs.h */ + BCM_FUN_ID_SPDSVC_TRANSMIT, + BCM_FUN_ID_SPDSVC_RECEIVE, + /* Kernel Bonding Driver related function */ + BCM_FUN_ID_BOND_CLR_SLAVE_STAT, + BCM_FUN_ID_ENET_IS_BONDED_LAN_WAN_PORT, /* Expects Logical port number as argument */ + BCM_FUN_ID_ENET_IS_DEV_IN_SLAVE_PATH, + BCM_FUN_ID_BOND_RX_HANDLER, + /* DSL Runner Hooks */ + BCM_FUN_ID_RUNNER_PREPEND, + BCM_FUN_ID_TCPSPDTEST_CONNECT, + /* Archer Hooks */ + BCM_FUN_ID_ARCHER_HOST_BIND, + BCM_FUN_ID_ARCHER_XTMRT_BIND, + BCM_FUN_ID_ARCHER_WFD_BIND, + BCM_FUN_ID_ARCHER_WFD_CONFIG, + BCM_FUN_ID_VLAN_LOOKUP_DP, + /* WLAN Hooks */ + BCM_FUN_ID_WLAN_QUERY_BRIDGEFDB, + BCM_FUN_ID_WLAN_UPDATE_BRIDGEFDB, + BCM_FUN_ID_SPDT_RNR_TRANSMIT, + BCM_FUN_ID_MAX +} bcmFunId_t; + +/* Structures passed in above function calls */ +typedef struct { + struct net_device *slave_dev; /* Input */ + struct net_device **bond_dev; /* Input/Output */ +}BCM_BondDevInfo; + +/* Structures passed in above function calls */ +typedef struct { + uint16_t gemPortIndex; /* Input */ + uint16_t gemPortId; /* Output */ + uint8_t usQueueIdx; /* Output */ +}BCM_GponGemPidQueueInfo; + +typedef enum { + BCM_ENET_FUN_TYPE_LEARN_CTRL = 0, + BCM_ENET_FUN_TYPE_ARL_WRITE, + BCM_ENET_FUN_TYPE_AGE_PORT, + BCM_ENET_FUN_TYPE_UNI_UNI_CTRL, + BCM_ENET_FUN_TYPE_PORT_RX_CTRL, + BCM_ENET_FUN_TYPE_GET_VPORT_CNT, + BCM_ENET_FUN_TYPE_GET_IF_NAME_OF_VPORT, + BCM_ENET_FUN_TYPE_GET_UNIPORT_MASK, + BCM_ENET_FUN_TYPE_MAX +} bcmFun_Type_t; + +typedef struct { + uint16_t vid; + uint16_t val; + uint8_t mac[6]; +} arlEntry_t; + +typedef struct { + bcmFun_Type_t type; /* Action Needed in Enet Driver */ + union { + uint8_t port; + uint8_t uniport_cnt; + uint16_t portMask; + arlEntry_t arl_entry; + }; + char name[16]; + uint8_t enable; +}BCM_EnetHandle_t; + +typedef enum { + BCM_EPON_FUN_TYPE_UNI_UNI_CTRL = 0, + BCM_EPON_FUN_TYPE_MAX +} bcmEponFun_Type_t; + +typedef struct { + bcmEponFun_Type_t type; /* Action Needed in Epon Driver */ + uint8_t enable; +}BCM_EponHandle_t; + +typedef struct { + uint8_t port; /* switch port */ + uint8_t enable; /* enable/disable the clock */ +}BCM_CmfFfeClk_t; + +#define BCM_RUNNER_PREPEND_SIZE_MAX 32 /* Increasing the size of the prepend data buffer will require + recompiling the pktrunner driver files released as binary */ + +typedef struct { + void *blog_p; /* INPUT: Pointer to the Blog_t structure that triggered the Runner flow creation */ + uint8_t data[BCM_RUNNER_PREPEND_SIZE_MAX]; /* INPUT: The data that will be be prepended to all packets + forwarded by Runner that match the given Blog/Flow. + The data must be stored in NETWWORK BYTE ORDER */ + unsigned int size; /* OUTPUT: Size of the prepend data, up to 32 bytes long. + When no data is to be prepended, specify size = 0 */ +} BCM_runnerPrepend_t; + +typedef struct { + unsigned int sysport; + unsigned int switch_id; + unsigned int port; + unsigned int is_wan; +} BCM_EnetPortRole_t; + +#define BCM_ENET_SYSPORT_INTF_MAX 2 +#define BCM_ENET_SYSPORT_BLOG_CHNL_MAX 8 + +typedef enum { + BCM_ENET_SYSPORT_MODE_INVALID = 0, + BCM_ENET_SYSPORT_MODE_PORT, + BCM_ENET_SYSPORT_MODE_INTERNAL_BRCM_SW, + BCM_ENET_SYSPORT_MODE_EXTERNAL_BRCM_SW, + BCM_ENET_SYSPORT_MODE_MAX +} bcmSysport_Mode_t; + +typedef struct { + bcmSysport_Mode_t mode; +} bcmSysport_Sysport_t; + +typedef struct { + struct net_device *dev; + int sysport; + int switch_id; + int port; + int nbr_of_queues; +} bcmSysport_BlogChnl_t; + +typedef struct { + int nbr_of_sysports; + bcmSysport_Sysport_t sysport[BCM_ENET_SYSPORT_INTF_MAX]; + int nbr_of_blog_channels; + bcmSysport_BlogChnl_t blog_chnl[BCM_ENET_SYSPORT_BLOG_CHNL_MAX]; +} bcmSysport_Config_t; + +#define BCM_ENET_SYSPORT_QUEUE_MAP_PRIORITY_MAX 8 + +typedef struct { + int blog_chnl; + uint8_t priority_to_switch_queue[BCM_ENET_SYSPORT_QUEUE_MAP_PRIORITY_MAX]; +} bcmSysport_QueueMap_t; + +typedef struct { + int blog_chnl; + int blog_chnl_rx; +} bcmEnet_BondRxPortMap_t; + +/* Structure used with BCM_FUN_ID_ENET_REMAP_TX_QUEUE */ +typedef struct { + uint8_t tx_queue; + void *dev; +} bcmEnet_QueueReMap_t; + +typedef struct { + struct net_device *dev; + int kbps; +} bcmSysport_PhySpeed_t; + +#endif /* _BCM_LOG_MODULES_ */ + diff --git a/include/linux/bcm_netdev_path.h b/include/linux/bcm_netdev_path.h new file mode 100644 index 0000000000000000000000000000000000000000..e35b551906cbc14dcc888872fad659ea86eccdb5 --- /dev/null +++ b/include/linux/bcm_netdev_path.h @@ -0,0 +1,109 @@ +#ifndef __BCM_NETDEV_PATH_H_INCLUDED__ +#define __BCM_NETDEV_PATH_H_INCLUDED__ + + +/* +<:copyright-BRCM:2013:DUAL/GPL:standard + + Copyright (c) 2013 Broadcom + All Rights Reserved + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + +/* Forward declaration */ +struct net_device; + +#define NETDEV_PATH_HW_SUBPORTS_MAX CONFIG_BCM_MAX_GEM_PORTS +struct netdev_path +{ + /* this reference counter indicates the number of interfaces + referencing this interface */ + int refcount; + /* indicates the RX hardware port number associated to the + interface */ + unsigned int hw_port; + /* indicates the TX hardware port number associated to the + interface */ + unsigned int hw_tx_port; + /* hardware port type, must be set to one of the types defined in + BlogPhy_t */ + unsigned int hw_port_type; + /* some device drivers support virtual subports within a hardware + port. hw_subport_mcast is used to map a multicast hw subport + to a hw port. */ + unsigned int hw_subport_mcast_idx; +}; + +/* Returns TRUE when _dev is a member of a path, otherwise FALSE */ +#define netdev_path_is_linked(_dev) ( netdev_path_next_dev(_dev) != NULL ) + +/* Returns TRUE when _dev is the leaf in a path, otherwise FALSE */ +#define netdev_path_is_leaf(_dev) ( (_dev)->bcm_nd_ext.path.refcount == 0 ) + +/* Returns TRUE when _dev is the root of a path, otherwise FALSE. The root + device is the physical device */ +#define netdev_path_is_root(_dev) ( netdev_path_next_dev(_dev) == NULL ) + +#define netdev_path_set_hw_port(_dev, _hw_port, _hw_port_type) \ + do { \ + (_dev)->bcm_nd_ext.path.hw_port = (_hw_port); \ + (_dev)->bcm_nd_ext.path.hw_tx_port = (_hw_port); \ + (_dev)->bcm_nd_ext.path.hw_port_type = (_hw_port_type); \ + } while(0) + +#define netdev_path_set_hw_port_only(_dev, _hw_port) \ + do { \ + (_dev)->bcm_nd_ext.path.hw_port = (_hw_port); \ + } while(0) + +#define netdev_path_set_hw_tx_port_only(_dev, _hw_port) \ + do { \ + (_dev)->bcm_nd_ext.path.hw_tx_port = (_hw_port); \ + } while(0) + +#define netdev_path_get_hw_port(_dev) ( (_dev)->bcm_nd_ext.path.hw_port ) + +#define netdev_path_get_hw_tx_port(_dev) ( (_dev)->bcm_nd_ext.path.hw_tx_port ) + +#define netdev_path_get_hw_port_type(_dev) ( (_dev)->bcm_nd_ext.path.hw_port_type ) +#define netdev_path_set_hw_port_type(_dev, _hwt) do { (_dev)->bcm_nd_ext.path.hw_port_type = _hwt; } while (0) + +#define netdev_path_get_hw_subport_mcast_idx(_dev) ( (_dev)->bcm_nd_ext.path.hw_subport_mcast_idx ) + +/* Returns a pointer to the next device in a path, towards the root + (physical) device */ +struct net_device *netdev_path_next_dev(struct net_device *dev); + +struct net_device *netdev_path_get_root(struct net_device *dev); + +int netdev_path_set_hw_subport_mcast_idx(struct net_device *dev, unsigned int subport_idx); + +int netdev_path_add(struct net_device *new_dev, struct net_device *next_dev); + +int netdev_path_remove(struct net_device *dev); + +void netdev_path_dump(struct net_device *dev); + + +#endif /* __BCM_NETDEV_PATH_H_INCLUDED__ */ diff --git a/include/linux/bcm_netdevice.h b/include/linux/bcm_netdevice.h new file mode 100644 index 0000000000000000000000000000000000000000..a86d0098d198294d52d04d11587729fa7c72aeee --- /dev/null +++ b/include/linux/bcm_netdevice.h @@ -0,0 +1,152 @@ +#ifndef __BCM_NETDEVICE_H_INCLUDED__ +#define __BCM_NETDEVICE_H_INCLUDED__ + + +/* +<:copyright-BRCM:2013:DUAL/GPL:standard + + Copyright (c) 2013 Broadcom + All Rights Reserved + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + +#if defined(CONFIG_BLOG) +#include <linux/blog.h> +#if defined(CONFIG_BCM_WLAN_MODULE) +#include <linux/bcm_dslcpe_wlan_info.h> +#endif +#endif +#include <linux/bcm_netdev_path.h> +#if defined(CONFIG_BCM_RDPA_BRIDGE) || defined(CONFIG_BCM_RDPA_BRIDGE_MODULE) +#include <linux/br_fp.h> +#endif +#include <uapi/linux/bcm_maclimit.h> + +#define BCM_IFF_WANDEV (1 << 0) +#define BCM_IFF_VLAN (1 << 1) +#define BCM_IFF_PPP (1 << 2) +#define BCM_IFF_HW_FDB (1 << 3) // this dev is enabled for hw MAC learning +#define BCM_IFF_HW_SWITCH (1 << 4) +#define BCM_IFF_WLANDEV (1 << 5) +#define BCM_IFF_BCM_DEV (1 << 6) +#define BCM_IFF_WLANDEV_NIC (1 << 7) +#define BCM_IFF_WLANDEV_DHD (1 << 8) + +#define BLOG_DEV_STAT_FLAG_INCLUDE_SW_UC (1<<0) /* Include SW accelerated Unicast stats */ +#define BLOG_DEV_STAT_FLAG_INCLUDE_HW_UC (1<<1) /* Include HW accelerated Unicast stats */ +#define BLOG_DEV_STAT_FLAG_INCLUDE_SW_MC (1<<2) /* Include SW accelerated Multicast stats */ +#define BLOG_DEV_STAT_FLAG_INCLUDE_HW_MC (1<<3) /* Include HW accelerated Multicast stats */ +#define BLOG_DEV_STAT_FLAG_INCLUDE_SW (BLOG_DEV_STAT_FLAG_INCLUDE_SW_UC|BLOG_DEV_STAT_FLAG_INCLUDE_SW_MC) +#define BLOG_DEV_STAT_FLAG_INCLUDE_HW (BLOG_DEV_STAT_FLAG_INCLUDE_HW_UC|BLOG_DEV_STAT_FLAG_INCLUDE_HW_MC) +#define BLOG_DEV_STAT_FLAG_INCLUDE_ALL (BLOG_DEV_STAT_FLAG_INCLUDE_SW|BLOG_DEV_STAT_FLAG_INCLUDE_HW) + +/* Info types to ask from different drivers */ +typedef enum { + BCM_NETDEV_TO_RDPA_IF, +} bcm_netdev_priv_info_type_t; +/* Output from driver corresponding to the info type */ +typedef union { + struct { + int rdpa_if; + } bcm_netdev_to_rdpa_if; +} bcm_netdev_priv_info_out_t; + +typedef int (*bcm_netdev_priv_info_get_cb_fn_t)(struct net_device *dev, + bcm_netdev_priv_info_type_t info_type, + bcm_netdev_priv_info_out_t *info_out); + +struct bcm_netdev_ext { + unsigned int iff_flags; + struct netdev_path path; +#if defined(CONFIG_BLOG) + BlogStats_t blog_stats; /* Cummulative stats of accelerated flows */ + unsigned int blog_stats_flags; /* Blog stats collection property for the device */ +#if defined(CONFIG_BCM_WLAN_MODULE) + /* runner multicast acceleration hook */ + wlan_client_get_info_t wlan_client_get_info; +#endif +#endif /* CONFIG_BLOG */ +#if defined(CONFIG_BCM_RDPA_BRIDGE) || defined(CONFIG_BCM_RDPA_BRIDGE_MODULE) + struct bcm_br_ext bcm_br_ext; +#endif + struct mac_limit mac_limit; + /* return 0-success, -1:failure (not supported or other error) */ + bcm_netdev_priv_info_get_cb_fn_t bcm_netdev_cb_fn; +}; + +#if defined(CONFIG_BLOG) && defined(CONFIG_BCM_WLAN_MODULE) +#define netdev_wlan_client_get_info(dev) ((dev)->bcm_nd_ext.wlan_client_get_info) +#else +#define netdev_wlan_client_get_info(dev) NULL +#endif + +#define bcm_netdev_ext_field_get(dev, f) ((dev)->bcm_nd_ext.f) +#define bcm_netdev_ext_field_get_ptr(dev, f) (&(dev)->bcm_nd_ext.f) +#define bcm_netdev_ext_field_set(dev, f, val) ((dev)->bcm_nd_ext.f = val) + +#define netdev_bcm_dev_set(_dev) (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_BCM_DEV +#define netdev_bcm_dev_unset(_dev) (_dev)->bcm_nd_ext.iff_flags &= ~BCM_IFF_BCM_DEV +#define is_netdev_bcm_dev(_dev) ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_BCM_DEV) + +#define netdev_wan_set(_dev) (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_WANDEV +#define netdev_wan_unset(_dev) (_dev)->bcm_nd_ext.iff_flags &= ~BCM_IFF_WANDEV +#define is_netdev_wan(_dev) ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_WANDEV) + +#define netdev_vlan_set(_dev) (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_VLAN +#define is_netdev_vlan(_dev) ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_VLAN) + +#define netdev_ppp_set(_dev) (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_PPP +#define is_netdev_ppp(_dev) ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_PPP) + +#define netdev_hw_fdb_set(_dev) (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_HW_FDB +#define netdev_hw_fdb_unset(_dev) (_dev)->bcm_nd_ext.iff_flags &= ~BCM_IFF_HW_FDB +#define is_netdev_hw_fdb(_dev) ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_HW_FDB) + +#define netdev_hw_switch_set(_dev) (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_HW_SWITCH +#define netdev_hw_switch_unset(_dev) (_dev)->bcm_nd_ext.iff_flags &= ~BCM_IFF_HW_SWITCH +#define is_netdev_hw_switch(_dev) ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_HW_SWITCH) + +#define netdev_wlan_set(_dev) (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_WLANDEV +#define netdev_wlan_unset(_dev) (_dev)->bcm_nd_ext.iff_flags &= ~BCM_IFF_WLANDEV +#define is_netdev_wlan(_dev) ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_WLANDEV) + +#define netdev_wlan_nic_set(_dev) (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_WLANDEV_NIC +#define netdev_wlan_nic_unset(_dev) (_dev)->bcm_nd_ext.iff_flags &= ~BCM_IFF_WLANDEV_NIC +#define is_netdev_wlan_nic(_dev) ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_WLANDEV_NIC) + +#define netdev_wlan_dhd_set(_dev) (_dev)->bcm_nd_ext.iff_flags |= BCM_IFF_WLANDEV_DHD +#define netdev_wlan_dhd_unset(_dev) (_dev)->bcm_nd_ext.iff_flags &= ~BCM_IFF_WLANDEV_DHD +#define is_netdev_wlan_dhd(_dev) ((_dev)->bcm_nd_ext.iff_flags & BCM_IFF_WLANDEV_DHD) + +// for NETDEV_CHANGEUPPER +#define is_netdev_br_port_add(_dev, _ptr) (netif_is_bridge_port(_dev) && ((struct netdev_notifier_changeupper_info *)(ptr))->linking) +#define is_netdev_br_port_del(_dev, _ptr) (netif_is_bridge_port(_dev) && !((struct netdev_notifier_changeupper_info *)(ptr))->linking) +#define netdev_get_bridge_master(_dev, _ptr) (((struct netdev_notifier_changeupper_info *)(ptr))->upper_dev) + +void bcm_netdev_ext_inherit(struct net_device *parent, struct net_device * child); + +int bcm_attach_vlan_hook(struct net_device *dev); +void bcm_detach_vlan_hook(struct net_device *dev); + +#endif /* __BCM_NETDEVICE_H_INCLUDED__ */ \ No newline at end of file diff --git a/include/linux/bcm_nf_conntrack.h b/include/linux/bcm_nf_conntrack.h new file mode 100644 index 0000000000000000000000000000000000000000..fe6f7ce1e3b4eecedaafc6371fd9e14247f697e0 --- /dev/null +++ b/include/linux/bcm_nf_conntrack.h @@ -0,0 +1,293 @@ +/* +* <:copyright-BRCM:2012:DUAL/GPL:standard +* +* Copyright (c) 2012 Broadcom +* All Rights Reserved +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed +* to you under the terms of the GNU General Public License version 2 +* (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +* with the following added to such license: +* +* As a special exception, the copyright holders of this software give +* you permission to link this software with independent modules, and +* to copy and distribute the resulting executable under terms of your +* choice, provided that you also meet, for each linked independent +* module, the terms and conditions of the license of that module. +* An independent module is a module which is not derived from this +* software. The special exception does not apply to any modifications +* of the software. +* +* Not withstanding the above, under no circumstances may you combine +* this software in any way with any other Broadcom software provided +* under a license other than the GPL, without Broadcom's express prior +* written consent. +* +:> +*/ + +#ifndef _BCM_NF_CONNTRACK_H +#define _BCM_NF_CONNTRACK_H + +#include <linux/types.h> +#include <linux/netfilter/nf_conntrack_common.h> +#include <net/netfilter/nf_conntrack.h> +#include <net/netfilter/nf_conntrack_helper.h> + +#include <linux/blog.h> +#include <linux/dpi.h> +#include <linux/iqos.h> + + +#if defined(CONFIG_BLOG) +static inline void bcm_nf_blog_ct_init(struct nf_conn *ct) +{ + /* no blog lock needed here */ + set_bit(IPS_BLOG_BIT, &ct->status); /* Enable conntrack blogging */ + ct->bcm_ext.blog_key[IP_CT_DIR_ORIGINAL] = BLOG_KEY_FC_INVALID; + ct->bcm_ext.blog_key[IP_CT_DIR_REPLY] = BLOG_KEY_FC_INVALID; +} + +static inline int bcm_nf_blog_destroy_conntrack(struct nf_conn *ct) +{ + blog_lock(); + pr_debug("%s(%px) blog keys[0x%08x,0x%08x]\n", __func__, + ct, ct->bcm_ext.blog_key[IP_CT_DIR_ORIGINAL], + ct->bcm_ext.blog_key[IP_CT_DIR_REPLY]); + + + /* Conntrack going away, notify blog client */ + if ((ct->bcm_ext.blog_key[IP_CT_DIR_ORIGINAL] != BLOG_KEY_FC_INVALID) || + (ct->bcm_ext.blog_key[IP_CT_DIR_REPLY] != BLOG_KEY_FC_INVALID)) { + + blog_notify(DESTROY_FLOWTRACK, (void*)ct, + (uint32_t)ct->bcm_ext.blog_key[IP_CT_DIR_ORIGINAL], + (uint32_t)ct->bcm_ext.blog_key[IP_CT_DIR_REPLY]); + } + + clear_bit(IPS_BLOG_BIT, &ct->status); /* Disable further blogging */ + blog_unlock(); + + return 0; +} + +static inline int bcm_nf_blog_link_ct(struct nf_conn *ct, enum ip_conntrack_info ctinfo, + struct sk_buff *skb, u_int16_t l3num, u_int8_t protonum) +{ + + /* here we dont need blog lock as this blog is owned by this skb */ + + struct nf_conn_help * help = nfct_help(ct); + + + if ((help != (struct nf_conn_help *)NULL) && + (help->helper != (struct nf_conntrack_helper *)NULL) && + (help->helper->name && strcmp(help->helper->name, "BCM-NAT"))) { + pr_debug("nf_conntrack_in: skb<%px> ct<%px> helper<%s> found\n", + skb, ct, help->helper->name); + clear_bit(IPS_BLOG_BIT, &ct->status); + } + + if (test_bit(IPS_BLOG_BIT, &ct->status)) { /* OK to blog ? */ + uint32_t ct_type=(l3num==PF_INET)?BLOG_PARAM2_IPV4:BLOG_PARAM2_IPV6; + pr_debug("nf_conntrack_in: skb<%px> blog<%px> ct<%px>\n", + skb, blog_ptr(skb), ct); + + if (protonum == IPPROTO_GRE) + ct_type = BLOG_PARAM2_GRE_IPV4; + + if(ntohs(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.udp.port) == BLOG_L2TP_PORT) + ct_type = BLOG_PARAM2_L2TP_IPV4; + + blog_link(FLOWTRACK, blog_ptr(skb), + (void*)ct, CTINFO2DIR(ctinfo), ct_type); + } else { + pr_debug("nf_conntrack_in: skb<%px> ct<%px> NOT BLOGible<%px>\n", + skb, ct, blog_ptr(skb)); + blog_skip(skb, blog_skip_reason_ct_status_donot_blog); /* No blogging */ + } + + return 0; +} + +static inline int bcm_nf_blog_update_timeout(struct nf_conn *ct, unsigned long extra_jiffies) +{ + blog_lock(); + + if ((ct->bcm_ext.blog_key[IP_CT_DIR_ORIGINAL] != BLOG_KEY_FC_INVALID) || + (ct->bcm_ext.blog_key[IP_CT_DIR_REPLY] != BLOG_KEY_FC_INVALID)) { + + unsigned int blog_key = (ct->bcm_ext.blog_key[IP_CT_DIR_ORIGINAL] != BLOG_KEY_FC_INVALID) ? + ct->bcm_ext.blog_key[IP_CT_DIR_ORIGINAL] : ct->bcm_ext.blog_key[IP_CT_DIR_REPLY]; + + blog_notify(UPDATE_FLOWTRACK_IDLE_TIMEOUT, (void*)ct, + blog_key, (uint32_t)(extra_jiffies/HZ)); + } + blog_unlock(); + + return 0; +} + +#endif /*CONFIG_BLOG */ + +static inline int nf_conntrack_ipv6_is_multicast(const __be32 ip6[4]) +{ + return ((ip6[0] & htonl(0xFF000000)) == htonl(0xFF000000)); +} + +static inline void bcm_nf_conn_set_iq_prio(struct nf_conn *ct, struct sk_buff *skb) +{ +#if IS_ENABLED(CONFIG_BCM_INGQOS) +#if defined(CONFIG_BLOG) + if (skb != NULL && skb->blog_p != NULL ) + ct->bcm_ext.iq_prio = (blog_iq(skb) == BLOG_IQ_PRIO_HIGH) ? IQOS_PRIO_HIGH : IQOS_PRIO_LOW; + else +#endif + { + + switch (nf_ct_l3num(ct)) { + case AF_INET: + ct->bcm_ext.iq_prio = ipv4_is_multicast(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip) ? IQOS_PRIO_HIGH : IQOS_PRIO_LOW; + break; + case AF_INET6: + ct->bcm_ext.iq_prio = nf_conntrack_ipv6_is_multicast(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip6) ? IQOS_PRIO_HIGH : IQOS_PRIO_LOW; + break; + default: + ct->bcm_ext.iq_prio = IQOS_PRIO_LOW; + } + } +#endif +} + +static inline void bcm_nf_iqos_destroy_conntrack(struct nf_conn *ct) +{ +#if IS_ENABLED(CONFIG_BCM_INGQOS) + if (test_bit(IPS_IQOS_BIT,&ct->status)) { + clear_bit(IPS_IQOS_BIT, &ct->status); + iqos_rem_L4port(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum, + ntohs(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.all), IQOS_ENT_DYN); + iqos_rem_L4port(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum, + ntohs(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all), IQOS_ENT_DYN); + } +#endif +} + +#if defined(CONFIG_BCM_NF_DERIVED_CONN) +static inline void bcm_nf_ct_derived_list_add(struct nf_conn *ct) +{ + BCM_DERIVED_CONN_LOCK_BH(); + + /* master ref count incremneted before calling this fcuntion */ + /* via exp->master safe, refcnt bumped in nf_ct_find_expectation */ + if(ct->master){ + + list_add(&ct->bcm_ext.derived_list, + &ct->master->bcm_ext.derived_connections); + } + + BCM_DERIVED_CONN_UNLOCK_BH(); +} + +static inline void bcm_nf_ct_derived_list_del(struct nf_conn *ct) +{ + BCM_DERIVED_CONN_LOCK_BH(); + if(ct->master){ + list_del(&ct->bcm_ext.derived_list); + } + + BCM_DERIVED_CONN_UNLOCK_BH(); +} +static inline void bcm_nf_ct_derived_conn_init(struct nf_conn *ct) +{ + INIT_LIST_HEAD(&ct->bcm_ext.derived_connections); + INIT_LIST_HEAD(&ct->bcm_ext.derived_list); + ct->bcm_ext.derived_timeout = 0; +} +#else + +static inline void bcm_nf_ct_derived_list_add(struct nf_conn *ct){}; +static inline void bcm_nf_ct_derived_list_del(struct nf_conn *ct){}; +static inline void bcm_nf_ct_derived_conn_init(struct nf_conn *ct){}; +#endif + + +static inline unsigned long bcm_nf_ct_refresh(struct nf_conn *ct, + unsigned long extra_jiffies) +{ +#if defined(CONFIG_BCM_NF_DERIVED_CONN) + /* when derived time out is set always use it */ + if(ct->bcm_ext.derived_timeout) + extra_jiffies = ct->bcm_ext.derived_timeout; +#endif + +#if defined(CONFIG_BLOG) + if( nf_ct_is_confirmed(ct) && (ct->bcm_ext.extra_jiffies != extra_jiffies)) { + ct->bcm_ext.extra_jiffies = extra_jiffies; + /*notify accelerator */ + bcm_nf_blog_update_timeout(ct, extra_jiffies); + } +#endif + + return extra_jiffies; +} + +static void bcm_conntrack_init_end(void) +{ +#if IS_ENABLED(CONFIG_BCM_DPI) + dpi_conntrack_init(); +#endif +} + +static void bcm_conntrack_cleanup_end(void) +{ +#if IS_ENABLED(CONFIG_BCM_DPI) + dpi_conntrack_cleanup(); +#endif +} + +static void bcm_nf_ct_alloc(struct nf_conn *ct, struct sk_buff *skb) +{ +#if defined(CONFIG_BLOG) + bcm_nf_blog_ct_init(ct); +#endif + /* REGARDLESS_DROP */ + INIT_LIST_HEAD(&ct->bcm_ext.safe_list); + + bcm_nf_ct_derived_conn_init(ct); + bcm_nf_conn_set_iq_prio(ct, skb); + +#if IS_ENABLED(CONFIG_BCM_DPI) + memset(&ct->bcm_ext.dpi, 0, sizeof(ct->bcm_ext.dpi)); + if (skb && skb->dev && is_netdev_wan(skb->dev)) + set_bit(DPI_CT_INIT_FROM_WAN_BIT, &ct->bcm_ext.dpi.flags); +#endif +#if IS_ENABLED(CONFIG_NF_DYNDSCP) + /* initialize dynamic dscp inheritance fields */ + ct->bcm_ext.dyndscp.status = 0; + ct->bcm_ext.dyndscp.dscp[0] = 0; + ct->bcm_ext.dyndscp.dscp[1] = 0; +#endif +} + +static void bcm_nf_ct_init(struct nf_conn *ct) +{ + bcm_nf_ct_derived_list_add(ct); +} + +static void bcm_nf_ct_delete(struct nf_conn *ct) +{ +#if IS_ENABLED(CONFIG_BCM_DPI) + dpi_nf_ct_delete(ct); +#endif +} + +static void bcm_nf_ct_destroy(struct nf_conn *ct) +{ +#if defined(CONFIG_BLOG) + bcm_nf_blog_destroy_conntrack(ct); +#endif + bcm_nf_iqos_destroy_conntrack(ct); + bcm_nf_ct_derived_list_del(ct); +} +#endif /* _BCM_NF_CONNTRACK_H */ diff --git a/include/linux/bcm_nf_regardlessdrop.h b/include/linux/bcm_nf_regardlessdrop.h new file mode 100644 index 0000000000000000000000000000000000000000..957e11d4577101d89eb59e90266de917f0605761 --- /dev/null +++ b/include/linux/bcm_nf_regardlessdrop.h @@ -0,0 +1,283 @@ +/* +* <:copyright-BRCM:2012:DUAL/GPL:standard +* +* Copyright (c) 2012 Broadcom +* All Rights Reserved +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed +* to you under the terms of the GNU General Public License version 2 +* (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +* with the following added to such license: +* +* As a special exception, the copyright holders of this software give +* you permission to link this software with independent modules, and +* to copy and distribute the resulting executable under terms of your +* choice, provided that you also meet, for each linked independent +* module, the terms and conditions of the license of that module. +* An independent module is a module which is not derived from this +* software. The special exception does not apply to any modifications +* of the software. +* +* Not withstanding the above, under no circumstances may you combine +* this software in any way with any other Broadcom software provided +* under a license other than the GPL, without Broadcom's express prior +* written consent. +* +:> +*/ + +#ifndef _BCM_NF_REGARDLESSDROP_ +#define _BCM_NF_REGARDLESSDROP_ + +#define NF_CT_SAFE_LISTS_MAX 6 +/* regardless drop of connection when conntrack table is full */ +struct safe_list { + spinlock_t lock; + struct list_head low; /* low priority linux only */ + struct list_head low_sw_accel; /* low priority sw acceleartor */ + struct list_head low_hw_accel; /* low priority hw accelerator */ + struct list_head hi; /* high priority linux only */ + struct list_head hi_sw_accel; /* high priority sw acceleartor */ + struct list_head hi_hw_accel; /* high priority hw accelerator */ + struct list_head *drop_list_order[NF_CT_SAFE_LISTS_MAX]; /*order in which lists are checked to drop a connection */ +}; + +struct safe_list ct_safe_lists = { + .lock = __SPIN_LOCK_UNLOCKED(ct_safe_lists.lock), + .low = LIST_HEAD_INIT(ct_safe_lists.low), + .low_sw_accel = LIST_HEAD_INIT(ct_safe_lists.low_sw_accel), + .low_hw_accel = LIST_HEAD_INIT(ct_safe_lists.low_hw_accel), + .hi = LIST_HEAD_INIT(ct_safe_lists.hi), + .hi_sw_accel = LIST_HEAD_INIT(ct_safe_lists.hi_sw_accel), + .hi_hw_accel = LIST_HEAD_INIT(ct_safe_lists.hi_hw_accel), +#if CONFIG_BCM_NETFILTER_REGARDLESS_DROP_ORDER == 1 + /* when trying to find a drop candidate search safe_list's in the order of + * non-accelerated-->sw_accelerated-->hw_accelerated + * this is the default policy + */ + .drop_list_order = {&ct_safe_lists.low, &ct_safe_lists.hi, + &ct_safe_lists.low_sw_accel,&ct_safe_lists.hi_sw_accel, + &ct_safe_lists.low_hw_accel, &ct_safe_lists.hi_hw_accel} +#elif CONFIG_BCM_NETFILTER_REGARDLESS_DROP_ORDER == 2 + .drop_list_order = {&ct_safe_lists.low, &ct_safe_lists.low_sw_accel, + &ct_safe_lists.hi, &ct_safe_lists.hi_sw_accel, + &ct_safe_lists.low_hw_accel, &ct_safe_lists.hi_hw_accel} +#elif CONFIG_BCM_NETFILTER_REGARDLESS_DROP_ORDER == 3 + .drop_list_order = {&ct_safe_lists.low, &ct_safe_lists.low_sw_accel, + &ct_safe_lists.low_hw_accel, &ct_safe_lists.hi, + &ct_safe_lists.hi_sw_accel, &ct_safe_lists.hi_hw_accel} +#else +#error "Netfilter Regardless Drop Order is not set" +#endif +}; + + +static inline void ct_set_curr_safe_list(struct nf_conn *ct) +{ + /*first try to move to HW list */ + if(ct->bcm_ext.hw_accel_flows) { +#if IS_ENABLED(CONFIG_BCM_INGQOS) + if (ct->bcm_ext.iq_prio == IQOS_PRIO_HIGH) + ct->bcm_ext.curr_safe_list = &ct_safe_lists.hi_hw_accel; + else +#endif + ct->bcm_ext.curr_safe_list = &ct_safe_lists.low_hw_accel; + }else if(ct->bcm_ext.sw_accel_flows) { +#if IS_ENABLED(CONFIG_BCM_INGQOS) + if (ct->bcm_ext.iq_prio == IQOS_PRIO_HIGH) + ct->bcm_ext.curr_safe_list = &ct_safe_lists.hi_sw_accel; + else +#endif + ct->bcm_ext.curr_safe_list = &ct_safe_lists.low_sw_accel; + }else{ + /*move to SW only list */ +#if IS_ENABLED(CONFIG_BCM_INGQOS) + if (ct->bcm_ext.iq_prio == IQOS_PRIO_HIGH) + ct->bcm_ext.curr_safe_list = &ct_safe_lists.hi; + else +#endif + ct->bcm_ext.curr_safe_list = &ct_safe_lists.low; + } +} + +static inline void ct_safe_list_add_tail(struct nf_conn *ct) +{ + spin_lock_bh(&ct_safe_lists.lock); + + ct->bcm_ext.hw_accel_flows = 0; + ct->bcm_ext.sw_accel_flows = 0; + + ct_set_curr_safe_list(ct); + + list_add_tail(&ct->bcm_ext.safe_list, ct->bcm_ext.curr_safe_list); + + spin_unlock_bh(&ct_safe_lists.lock); +} + +static inline void ct_safe_list_move_tail(struct nf_conn *ct) +{ + spin_lock_bh(&ct_safe_lists.lock); + + list_move_tail(&ct->bcm_ext.safe_list, ct->bcm_ext.curr_safe_list); + + spin_unlock_bh(&ct_safe_lists.lock); +} + +static inline void ct_safe_list_del(struct nf_conn *ct) +{ + spin_lock_bh(&ct_safe_lists.lock); + list_del(&ct->bcm_ext.safe_list); + spin_unlock_bh(&ct_safe_lists.lock); +} + +#if defined(CONFIG_BLOG) + +static inline void __ct_blog_flow_accel_activate_event(struct nf_conn *ct, + BlogFlowEventInfo_t *info) +{ + spin_lock_bh(&ct_safe_lists.lock); + /* ensure ct is not being deleted */ + if(likely(atomic_read(&ct->ct_general.use) >= 1)) + { + if(info->flow_event_type == FLOW_EVENT_TYPE_HW) + ct->bcm_ext.hw_accel_flows++; + else + ct->bcm_ext.sw_accel_flows++; + + ct_set_curr_safe_list(ct); + + list_move_tail(&ct->bcm_ext.safe_list, ct->bcm_ext.curr_safe_list); + } + spin_unlock_bh(&ct_safe_lists.lock); +} + +static inline void ct_blog_flow_activate_event(BlogFlowEventInfo_t *info) +{ + + if ((info->flow_event_type == FLOW_EVENT_TYPE_FC) || + (info->flow_event_type == FLOW_EVENT_TYPE_HW)){ + + __ct_blog_flow_accel_activate_event(info->ct_pld_p, info); + + if(info->ct_del_p) + __ct_blog_flow_accel_activate_event(info->ct_del_p, info); + } +} + +static inline void __ct_blog_flow_accel_deactivate_event(struct nf_conn *ct, + BlogFlowEventInfo_t *info) +{ + spin_lock_bh(&ct_safe_lists.lock); + /* ensure ct is not being deleted */ + if(likely(atomic_read(&ct->ct_general.use) >= 1)){ + + if(info->flow_event_type == FLOW_EVENT_TYPE_HW) + ct->bcm_ext.hw_accel_flows--; + else + ct->bcm_ext.sw_accel_flows--; + + ct_set_curr_safe_list(ct); + + list_move_tail(&ct->bcm_ext.safe_list, ct->bcm_ext.curr_safe_list); + } + spin_unlock_bh(&ct_safe_lists.lock); +} + +static inline void ct_blog_flow_deactivate_event( BlogFlowEventInfo_t *info) +{ + if ((info->flow_event_type == FLOW_EVENT_TYPE_FC) || + (info->flow_event_type == FLOW_EVENT_TYPE_HW)){ + + __ct_blog_flow_accel_deactivate_event(info->ct_pld_p, info); + + if(info->ct_del_p) + __ct_blog_flow_accel_deactivate_event(info->ct_del_p, info); + } +} + +static int ct_blog_flowevent_notify(struct notifier_block * nb, + unsigned long event, void *info) +{ + switch(event){ + + case FLOW_EVENT_ACTIVATE: + ct_blog_flow_activate_event(info); + break; + + case FLOW_EVENT_DEACTIVATE: + ct_blog_flow_deactivate_event(info); + break; + + default: + break; + + } + return NOTIFY_OK; +} + +#endif /*CONFIG_BLOG */ + + +/*caller must have safe_list lock acquired */ +static inline struct nf_conn* __ct_find_drop_candidate(struct net *net, struct list_head *list ) +{ + struct list_head *tmp; + struct nf_conn *ct, *ct_candidate=NULL; + + if (!list_empty(list)) { + list_for_each(tmp, list) { + ct = container_of(tmp, struct nf_conn, bcm_ext.safe_list); + + /*TODO IPS_OFFLOAD_BIT, should we check all lists or only sw only lists*/ + + + if (likely(!test_bit(IPS_OFFLOAD_BIT, &ct->status) && nf_ct_is_confirmed(ct) + && !nf_ct_is_dying(ct) && net_eq(nf_ct_net(ct), net) + && atomic_inc_not_zero(&ct->ct_general.use))) { + + /* we dont need to check if connection is expired or not to drop it, + * or trrigger gc, as we are already using LRU + */ + ct_candidate = ct; + /* move to the tail of the list while it's being deleted*/ + list_move_tail(&ct_candidate->bcm_ext.safe_list, list); + break; + } + } + } + /* refcount of ct_candidate is incremented in this fucntion, + * it's callers responsibility to decrement it + */ + return ct_candidate; +} + +/* Choose a LRU connection based on the configured drop order policy */ +static int bcm_regardless_drop(struct net *net) +{ + struct nf_conn *ct_candidate = NULL; + int i,dropped = 0; + + spin_lock_bh(&ct_safe_lists.lock); + + for( i=0; i < NF_CT_SAFE_LISTS_MAX; i++ ) { + ct_candidate = __ct_find_drop_candidate(net, ct_safe_lists.drop_list_order[i]); + if(ct_candidate) + break; + } + + spin_unlock_bh(&ct_safe_lists.lock); + + if (unlikely(ct_candidate == NULL)) + return dropped; + + if(nf_ct_delete(ct_candidate, 0, 0) == true){ + dropped = 1; + NF_CT_STAT_INC_ATOMIC(net, early_drop); + } + + nf_ct_put(ct_candidate); + return dropped; +} + +#endif /* _BCM_NF_REGARDLESSDROP_ */ diff --git a/include/linux/bcm_nfconn_ext.h b/include/linux/bcm_nfconn_ext.h new file mode 100644 index 0000000000000000000000000000000000000000..3a79fd4a9d8e92b6f7df4c178bec8ed524922287 --- /dev/null +++ b/include/linux/bcm_nfconn_ext.h @@ -0,0 +1,85 @@ +#ifndef _BCM_NFCONN_EXT_H +#define _BCM_NFCONN_EXT_H + +/* +<:copyright-BRCM:2013:DUAL/GPL:standard + + Copyright (c) 2013 Broadcom + All Rights Reserved + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + +#include <linux/dpi.h> + +struct bcm_nf_conn_ext { +#if defined(CONFIG_BLOG) + unsigned int blog_key[2]; /* Associating 2=IP_CT_DIR_MAX blogged flows */ + unsigned long extra_jiffies; /* connection timeout value */ +#endif + +#if defined(CONFIG_BCM_KF_NF_REGARDLESS_DROP) + uint32_t hw_accel_flows; /* Number of HW accelerated flows, need 32 bit for tunnel connection */ + uint32_t sw_accel_flows; /* Number of SW accelerated flows, need 32 bit for tunnel connection */ + struct list_head safe_list; /* regardless drop of connections */ + struct list_head *curr_safe_list; /* current safe_list for this connection*/ +#endif + +#if defined(CONFIG_BCM_NF_DERIVED_CONN) + struct list_head derived_connections; /* Used by master connection */ + struct list_head derived_list; /* Used by child connection */ + unsigned int derived_timeout; /* if non-zero override linux timeout */ +#endif + +#if IS_ENABLED(CONFIG_BCM_INGQOS) + uint8_t iq_prio; /* Ingress QoS Prio */ + uint8_t unused0; + uint16_t unused1; +#endif + +#if IS_ENABLED(CONFIG_NF_DYNDSCP) + struct nf_tos_inheritance { + u_int16_t status; + u_int8_t dscp[2]; /* IP_CT_DIR_MAX */ + } dyndscp; +#endif +#if IS_ENABLED(CONFIG_BCM_DPI) + struct dpi_info dpi; +#endif +}; + +#define bcm_nfconn_ext_field_get(ct, f) (ct->bcm_ext.f) +#define bcm_nfconn_ext_field_get_ptr(ct, f) (&ct->bcm_ext.f) +#define bcm_nfconn_ext_field_set(ct, f, val) (ct->bcm_ext.f = val) + +#if defined(CONFIG_BCM_NF_DERIVED_CONN) +extern spinlock_t bcm_derived_conn_lock; +#define BCM_DERIVED_CONN_LOCK_BH() spin_lock_bh(&bcm_derived_conn_lock) +#define BCM_DERIVED_CONN_UNLOCK_BH() spin_unlock_bh(&bcm_derived_conn_lock) +#endif + + +int ct_show_bcm_ext(struct seq_file *s, const struct nf_conn *ct); + + +#endif /*_BCM_NFCONN_EXT_H */ diff --git a/include/linux/bcm_skb_defines.h b/include/linux/bcm_skb_defines.h new file mode 100644 index 0000000000000000000000000000000000000000..4acb80265551ba45564bb12f674bcc5aaabb0316 --- /dev/null +++ b/include/linux/bcm_skb_defines.h @@ -0,0 +1,149 @@ +/* +* <:copyright-BRCM:2014:DUAL/GPL:standard +* +* Copyright (c) 2014 Broadcom +* All Rights Reserved +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed +* to you under the terms of the GNU General Public License version 2 +* (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +* with the following added to such license: +* +* As a special exception, the copyright holders of this software give +* you permission to link this software with independent modules, and +* to copy and distribute the resulting executable under terms of your +* choice, provided that you also meet, for each linked independent +* module, the terms and conditions of the license of that module. +* An independent module is a module which is not derived from this +* software. The special exception does not apply to any modifications +* of the software. +* +* Not withstanding the above, under no circumstances may you combine +* this software in any way with any other Broadcom software provided +* under a license other than the GPL, without Broadcom's express prior +* written consent. +* +* :> +*/ + +#ifndef _BCM_SKB_DEFINES_ +#define _BCM_SKB_DEFINES_ + +/* queue = mark[4:0] */ +#define SKBMARK_Q_S 0 +#define SKBMARK_Q_M (0x1F << SKBMARK_Q_S) +#define SKBMARK_GET_Q(MARK) ((MARK & SKBMARK_Q_M) >> SKBMARK_Q_S) +#define SKBMARK_SET_Q(MARK, Q) ((MARK & ~SKBMARK_Q_M) | (Q << SKBMARK_Q_S)) +/* traffic_class_id = mark[10:5] */ +#define SKBMARK_TC_ID_S 5 +#define SKBMARK_TC_ID_M (0x3F << SKBMARK_TC_ID_S) +#define SKBMARK_GET_TC_ID(MARK) ((MARK & SKBMARK_TC_ID_M) >> SKBMARK_TC_ID_S) +#define SKBMARK_SET_TC_ID(MARK, TC) \ + ((MARK & ~SKBMARK_TC_ID_M) | (TC << SKBMARK_TC_ID_S)) +/* flow_id = mark[18:11] */ +#define SKBMARK_FLOW_ID_S 11 +#define SKBMARK_FLOW_ID_M (0xFF << SKBMARK_FLOW_ID_S) +#define SKBMARK_GET_FLOW_ID(MARK) \ + ((MARK & SKBMARK_FLOW_ID_M) >> SKBMARK_FLOW_ID_S) +#define SKBMARK_SET_FLOW_ID(MARK, FLOW) \ + ((MARK & ~SKBMARK_FLOW_ID_M) | (FLOW << SKBMARK_FLOW_ID_S)) +/* iq_prio = mark[19]; for Ingress QoS used when TX is WLAN */ +#define SKBMARK_IQPRIO_MARK_S 19 +#define SKBMARK_IQPRIO_MARK_M (0x01 << SKBMARK_IQPRIO_MARK_S) +#define SKBMARK_GET_IQPRIO_MARK(MARK) \ + ((MARK & SKBMARK_IQPRIO_MARK_M) >> SKBMARK_IQPRIO_MARK_S) +#define SKBMARK_SET_IQPRIO_MARK(MARK, IQPRIO_MARK) \ + ((MARK & ~SKBMARK_IQPRIO_MARK_M) | (IQPRIO_MARK << SKBMARK_IQPRIO_MARK_S)) +/* port = mark[26:20]; for enet driver of gpon port, this is gem_id */ +#define SKBMARK_PORT_S 20 +#define SKBMARK_PORT_M (0x7F << SKBMARK_PORT_S) +#define SKBMARK_GET_PORT(MARK) \ + ((MARK & SKBMARK_PORT_M) >> SKBMARK_PORT_S) +#define SKBMARK_SET_PORT(MARK, PORT) \ + ((MARK & ~SKBMARK_PORT_M) | (PORT << SKBMARK_PORT_S)) + +/* iffwan_mark = mark[27] -- BRCM defined-- */ +#define SKBMARK_IFFWAN_MARK_S 27 +#define SKBMARK_IFFWAN_MARK_M (0x01 << SKBMARK_IFFWAN_MARK_S) +#define SKBMARK_GET_IFFWAN_MARK(MARK) \ + ((MARK & SKBMARK_IFFWAN_MARK_M) >> SKBMARK_IFFWAN_MARK_S) +#define SKBMARK_SET_IFFWAN_MARK(MARK, IFFWAN_MARK) \ + ((MARK & ~SKBMARK_IFFWAN_MARK_M) | (IFFWAN_MARK << SKBMARK_IFFWAN_MARK_S)) + +/* ipsec_mark = mark[28] */ +#define SKBMARK_IPSEC_MARK_S 28 +#define SKBMARK_IPSEC_MARK_M (0x01 << SKBMARK_IPSEC_MARK_S) +#define SKBMARK_GET_IPSEC_MARK(MARK) \ + ((MARK & SKBMARK_IPSEC_MARK_M) >> SKBMARK_IPSEC_MARK_S) +#define SKBMARK_SET_IPSEC_MARK(MARK, IPSEC_MARK) \ + ((MARK & ~SKBMARK_IPSEC_MARK_M) | (IPSEC_MARK << SKBMARK_IPSEC_MARK_S)) +/* policy_routing = mark[31:29] */ +#define SKBMARK_POLICY_RTNG_S 29 +#define SKBMARK_POLICY_RTNG_M (0x07 << SKBMARK_POLICY_RTNG_S) +#define SKBMARK_GET_POLICY_RTNG(MARK) \ + ((MARK & SKBMARK_POLICY_RTNG_M) >> SKBMARK_POLICY_RTNG_S) +#define SKBMARK_SET_POLICY_RTNG(MARK, POLICY) \ + ((MARK & ~SKBMARK_POLICY_RTNG_M) | (POLICY << SKBMARK_POLICY_RTNG_S)) + +/* dpi_queue = mark[31:27] */ +/* Overlaps with SKBMARK_IFFWAN, SKBMARK_IPSEC, and SKBMARK_POLICY_RTNG */ +#define SKBMARK_DPIQ_MARK_S 27 +#define SKBMARK_DPIQ_MARK_M (0x1F << SKBMARK_DPIQ_MARK_S) +#define SKBMARK_GET_DPIQ_MARK(MARK) \ + ((MARK & SKBMARK_DPIQ_MARK_M) >> SKBMARK_DPIQ_MARK_S) +#define SKBMARK_SET_DPIQ_MARK(MARK, DPIQ_MARK) \ + ((MARK & ~SKBMARK_DPIQ_MARK_M) | (DPIQ_MARK << SKBMARK_DPIQ_MARK_S)) + +/* The enet driver subdivides queue field (mark[4:0]) in the skb->mark into + priority and channel */ +/* priority = queue[2:0] (=>mark[2:0]) */ +#define SKBMARK_Q_PRIO_S (SKBMARK_Q_S) +#define SKBMARK_Q_PRIO_M (0x07 << SKBMARK_Q_PRIO_S) +#define SKBMARK_GET_Q_PRIO(MARK) \ + ((MARK & SKBMARK_Q_PRIO_M) >> SKBMARK_Q_PRIO_S) +#define SKBMARK_SET_Q_PRIO(MARK, Q) \ + ((MARK & ~SKBMARK_Q_PRIO_M) | (Q << SKBMARK_Q_PRIO_S)) +/* channel = queue[4:3] (=>mark[4:3]) */ +#define SKBMARK_Q_CH_S (SKBMARK_Q_S + 3) +#define SKBMARK_Q_CH_M (0x03 << SKBMARK_Q_CH_S) +#define SKBMARK_GET_Q_CHANNEL(MARK) ((MARK & SKBMARK_Q_CH_M) >> SKBMARK_Q_CH_S) +#define SKBMARK_SET_Q_CHANNEL(MARK, CH) \ + ((MARK & ~SKBMARK_Q_CH_M) | (CH << SKBMARK_Q_CH_S)) +/* service_queue_enable_mark = mark[4] -- DS BRCM defined-- */ +#define SKBMARK_SQ_MARK_S 4 +#define SKBMARK_SQ_MARK_M (0x01 << SKBMARK_SQ_MARK_S) +#define SKBMARK_GET_SQ_MARK(MARK) \ + ((MARK & SKBMARK_SQ_MARK_M) >> SKBMARK_SQ_MARK_S) +#define SKBMARK_SET_SQ_MARK(MARK, SQ_MARK) \ + ((MARK & ~SKBMARK_SQ_MARK_M) | (SQ_MARK << SKBMARK_SQ_MARK_S)) + +#define SKBMARK_ALL_GEM_PORT (0xFF) + +#define WLAN_PRIORITY_BIT_POS (1) +#define WLAN_PRIORITY_MASK (0x7 << WLAN_PRIORITY_BIT_POS) +#define GET_WLAN_PRIORITY(VAL) ((VAL & WLAN_PRIORITY_MASK) >> WLAN_PRIORITY_BIT_POS) +#define SET_WLAN_PRIORITY(ENCODEVAL, PRIO) ((ENCODEVAL & (~WLAN_PRIORITY_MASK)) | (PRIO << WLAN_PRIORITY_BIT_POS)) + +#define WLAN_IQPRIO_BIT_POS (0) +#define WLAN_IQPRIO_MASK (0x1 << WLAN_IQPRIO_BIT_POS) +#define GET_WLAN_IQPRIO(VAL) ((VAL & WLAN_IQPRIO_MASK) >> WLAN_IQPRIO_BIT_POS) +#define SET_WLAN_IQPRIO(ENCODEVAL, IQPRIO) ((ENCODEVAL & (~WLAN_IQPRIO_MASK)) | (IQPRIO << WLAN_IQPRIO_BIT_POS)) + +// LINUX_PRIORITY_BIT_POS_IN_MARK macro must be in sync with PRIO_LOC_NFMARK (=>mark[2:0]) +#define PRIO_LOC_NFMARK SKBMARK_Q_PRIO_S +#define LINUX_PRIORITY_BIT_POS_IN_MARK SKBMARK_Q_PRIO_S +#define LINUX_PRIORITY_BIT_MASK SKBMARK_Q_PRIO_M +#define LINUX_GET_PRIO_MARK(MARK) ((MARK & LINUX_PRIORITY_BIT_MASK) >> LINUX_PRIORITY_BIT_POS_IN_MARK) +#define LINUX_SET_PRIO_MARK(MARK, PRIO) ((MARK & (~LINUX_PRIORITY_BIT_MASK)) | (PRIO << LINUX_PRIORITY_BIT_POS_IN_MARK)) + +//Encode 3 bits of priority and 1 bit of IQPRIO into 4 bits as follows (3bitPrio:1bitIQPrio) +#define ENCODE_WLAN_PRIORITY_MARK(u8EncodeVal, u32Mark) \ + (u8EncodeVal = SET_WLAN_PRIORITY(u8EncodeVal, LINUX_GET_PRIO_MARK(u32Mark)) | SET_WLAN_IQPRIO(u8EncodeVal, SKBMARK_GET_IQPRIO_MARK(u32Mark))) +#define DECODE_WLAN_PRIORITY_MARK(encodedVal, u32Mark) \ + do { (u32Mark) = LINUX_SET_PRIO_MARK(u32Mark, GET_WLAN_PRIORITY(encodedVal)); \ + (u32Mark) = SKBMARK_SET_IQPRIO_MARK(u32Mark, GET_WLAN_IQPRIO(encodedVal)); \ + } while(0) + + +#endif /* _BCM_SKB_DEFINES_ */ diff --git a/include/linux/bcm_skbuff.h b/include/linux/bcm_skbuff.h new file mode 100644 index 0000000000000000000000000000000000000000..94b9ad73f98e79b101b948f44f2a386ad9fb79e1 --- /dev/null +++ b/include/linux/bcm_skbuff.h @@ -0,0 +1,525 @@ +#ifndef _BCM_SKBUFF_H +#define _BCM_SKBUFF_H + +#include <linux/net.h> + +#define CONFIG_SKBSHINFO_HAS_DIRTYP 1 + +struct blog_t; /* defined(CONFIG_BLOG) */ +struct net_device; + +#ifndef NULL_STMT +#define NULL_STMT do { /* NULL BODY */ } while (0) +#endif + +typedef void (*RecycleFuncP)(void *nbuff_p, unsigned long context, uint32_t flags); + +#define SKB_DATA_RECYCLE (1 << 0) +#define SKB_DATA_NO_RECYCLE (~SKB_DATA_RECYCLE) +#define SKB_RECYCLE (1 << 1) +#define SKB_NO_RECYCLE (~SKB_RECYCLE) +#define SKB_RECYCLE_NOFREE (1 << 2) /* DO NOT USE */ +#define SKB_RECYCLE_FPM_DATA (1 << 3) /* Data buffer from Runner FPM pool */ +#define SKB_RNR_FLOOD (1 << 4) /* Data buffer flooded by Runner to flooding-capable ports */ +/* Indicates whether a sk_buf or a data buffer is in BPM pristine state */ +#define SKB_BPM_PRISTINE (1 << 5) +/* UDP Speed Test flags */ +#define SKB_RNR_UDPSPDT_BASIC (1 << 6) +#define SKB_RNR_UDPSPDT_IPERF3 (1 << 7) + +#define SKB_RNR_FLAGS (SKB_RNR_FLOOD | SKB_RNR_UDPSPDT_BASIC | SKB_RNR_UDPSPDT_IPERF3) +#define SKB_RNR_UDPSPDT_FLAGS (SKB_RNR_UDPSPDT_BASIC | SKB_RNR_UDPSPDT_IPERF3) + +#define SKB_BPM_TAINTED(skb) \ +({ \ + ((struct sk_buff *)skb)->recycle_flags &= ~SKB_BPM_PRISTINE; \ + (skb_shinfo(skb))->dirty_p = NULL; \ +}) + + +#define SKB_DATA_PRISTINE(skb) \ +({ \ + (skb_shinfo(skb))->dirty_p = ((struct sk_buff *)skb)->head; \ +}) + +struct fkbuff; + +extern void skb_frag_xmit4(struct sk_buff *origskb, struct net_device *txdev, + uint32_t is_pppoe, uint32_t minMtu, void *ip_p); +extern void skb_frag_xmit6(struct sk_buff *origskb, struct net_device *txdev, + uint32_t is_pppoe, uint32_t minMtu, void *ip_p); +extern struct sk_buff *skb_xlate(struct fkbuff *fkb_p); +extern struct sk_buff *skb_xlate_dp(struct fkbuff *fkb_p, uint8_t *dirty_p); +extern int skb_avail_headroom(const struct sk_buff *skb); +extern void skb_bpm_tainted(struct sk_buff *skb); + +extern int skb_avail_headroom(const struct sk_buff *skb); + +extern void skb_cb_zero(struct sk_buff *skb); + +extern size_t skb_size(void); +extern size_t skb_aligned_size(void); +extern int skb_layout_test(int head_offset, int tail_offset, int end_offset); + +/** + * skb_headerinit - initialize a socket buffer header + * @headroom: reserved headroom size + * @datalen: data buffer size, data buffer is allocated by caller + * @skb: skb allocated by caller + * @data: data buffer allocated by caller + * @recycle_hook: callback function to free data buffer and skb + * @recycle_context: context value passed to recycle_hook, param1 + * @blog_p: pass a blog to a skb for logging + * + * Initializes the socket buffer and assigns the data buffer to it. + * Both the sk_buff and the pointed data buffer are pre-allocated. + * + */ +void skb_headerinit(unsigned int headroom, unsigned int datalen, + struct sk_buff *skb, unsigned char *data, + RecycleFuncP recycle_hook, unsigned long recycle_context, + struct blog_t *blog_p); + + +/* TODO avoid this detail here, nbuff/skbuff should just define this as + * uint32_t and wl driver should cast this to appropriate structure + */ +typedef union wlFlowInf { + uint32_t u32; + union { + union { + struct { + /* Start - Shared fields between ucast and mcast */ + uint32_t is_ucast:1; + /* wl_prio is 4 bits for nic and 3 bits for dhd. Plan is + * to make NIC as 3 bits after more analysis */ + uint32_t wl_prio:4; + /* End - Shared fields between ucast and mcast */ + uint32_t nic_reserved1:11; + uint32_t wl_chainidx:16; + }; + struct { + uint32_t overlayed_field:16; + uint32_t ssid_dst:16; /* For bridged traffic we don't have chainidx (0xFE) */ + }; + } nic; + + struct { + /* Start - Shared fields between ucast and mcast */ + uint32_t is_ucast:1; + uint32_t wl_prio:4; + /* End - Shared fields between ucast and mcast */ + /* Start - Shared fields between dhd ucast and dhd mcast */ + uint32_t flowring_idx:10; + /* End - Shared fields between dhd ucast and dhd mcast */ + uint32_t dhd_reserved:13; + uint32_t ssid:4; + } dhd; + } ucast; + struct { + /* Start - Shared fields between ucast and mcast */ + /* for multicast, WFD does not need to populate this flowring_idx, it is used internally by dhd driver */ + uint32_t is_ucast:1; + uint32_t wl_prio:4; + /* End - Shared fields between ucast and mcast */ + /* Start - Shared fields between dhd ucast and dhd mcast */ + uint32_t flowring_idx:10; + /* End - Shared fields between dhd ucast and dhd mcast */ + uint32_t mcast_reserved:1; + uint32_t ssid_vector:16; + } mcast; + + struct { + /* Start - Shared fields b/w ucast, mcast & pktfwd */ + uint32_t is_ucast : 1; /* Start - Shared fields b/w ucast, mcast */ + uint32_t wl_prio : 4; /* packet priority */ + /* End - Shared fields between ucast, mcast & pktfwd */ + uint32_t pktfwd_reserved : 7; + uint32_t ssid : 4; + uint32_t pktfwd_key : 16; /* pktfwd_key_t : 2b domain, 2b incarn, 12b index */ + } pktfwd; +} wlFlowInf_t; + +struct wlan_ext { + + union { + __u32 wl_cb[6]; + struct { + /* pktc_cb should hold space for void* and unsigned int */ + unsigned char pktc_cb[16]; + __u16 pktc_flags; /* wl_flags */ + __u16 dma_index; /* used by HND router for NIC Bulk Tx */ + __u8 wl_flag1; /* used for blog handle, only need one bit for now */ + __u8 wl_rsvd; + __u16 wl_flowid; /* cfp flowid */ + }; + } __aligned(8); +}; + +#define SKB_VLAN_MAX_TAGS 4 + +struct vlan_ext { + union { + struct { + __u32 reserved:31; + __u32 restore_rx_vlan:1; /* Restore Rx VLAN at xmit. Used in ONT mode */ + }; + __u32 bcm_flags_word; + } bcm_flags; + __u16 vlan_count; + __u16 vlan_tpid; + __u32 cfi_save; + __u32 vlan_header[SKB_VLAN_MAX_TAGS]; + struct net_device *rxdev; +}; + +#define MAP_FORWARD_NONE 0 +#define MAP_FORWARD_MODE1 1 +#define MAP_FORWARD_MODE2 2 +#define MAP_FORWARD_MODE3 3 /* MAP-E Pre-Fragmentation */ + +struct map_ext { + __u8 map_forward:2; + __u8 map_mf:1; + __u32 map_offset; + __u32 map_id; +}; + +struct bcm_skb_ext { + struct wlan_ext wlan; + struct vlan_ext vlan; + struct map_ext map; + + void *tunl; /* used to store tunl pointer */ + + unsigned char *clone_wr_head; /* indicates drivers(ex:enet)about writable headroom in aggregated skb */ + unsigned char *clone_fc_head; /* indicates fcache about writable headroom in aggregated skb */ + + struct net_device *in_dev; /* Physical device where this pkt is received */ +}; + +/* accessor macro */ +#define skbuff_bcm_ext_wlan_get(_skb, _field) ((_skb)->bcm_ext.wlan._field) +#define skbuff_bcm_ext_vlan_get(_skb, _field) ((_skb)->bcm_ext.vlan._field) +#define skbuff_bcm_ext_map_get(_skb, _field) ((_skb)->bcm_ext.map._field) +#define skbuff_bcm_ext_indev_get(_skb) ((_skb)->bcm_ext.in_dev) +#define skbuff_bcm_ext_indev_set(_skb, _dev) ((_skb)->bcm_ext.in_dev = _dev) + +void bcm_skbuff_copy_skb_header(struct sk_buff *new, const struct sk_buff *old); +void bcm_skbuff_skb_clone(struct sk_buff *n, struct sk_buff *skb); +void bcm_skbuff_handle_netif_rx_internal(struct sk_buff *skb); +void bcm_skbuff_handle_netif_receive_skb_core(struct sk_buff *skb); + +#if (defined(CONFIG_BCM_WLAN) || defined(CONFIG_BCM_WLAN_MODULE)) +int bcm_hook_br_handle_frame_finish(struct sk_buff *skb, int state); +int bcm_hook_br_should_deliver(struct sk_buff *skb, int state); +#else /* !CONFIG_BCM_WLAN */ +#define bcm_hook_br_handle_frame_finish(skb, state) 0 +#define bcm_hook_br_should_deliver(skb, state) 0 +#endif /* !CONFIG_BCM_WLAN */ + +#if defined(CONFIG_BCM_USBNET_ACCELERATION) +void skb_clone_headers_set(struct sk_buff *skb, unsigned int len); +unsigned int skb_writable_headroom(const struct sk_buff *skb); +#endif +void skb_header_free(struct sk_buff *skb); +struct sk_buff *skb_header_alloc(void); + +void skb_shinforeset(struct skb_shared_info *skb_shinfo); + +/* + * sk_buff structure is copied directly from skbuff.h and removing any #ifdef except CONFIG_BCM_KF_NBUFF. + * This is on-purpose to solve binary incompatibility issue. + */ + +#if defined(CONFIG_BCM_KF_MPTCP) +#define BCM_SKB_CB_SIZE 80 +#else +#define BCM_SKB_CB_SIZE 48 +#endif + +struct sk_buff { + union { + struct { + /* These two members must be first. */ + struct sk_buff *next; + struct sk_buff *prev; + + union { + struct net_device *dev; + /* Some protocols might use this space to store information, + * while device pointer would be NULL. + * UDP receive path is one user. + */ + unsigned long dev_scratch; + }; + }; + struct rb_node rbnode; /* used in netem, ip4 defrag, and tcp stack */ + struct list_head list; + }; + + union { + struct sock *sk; + int ip_defrag_offset; + }; + + union { + ktime_t tstamp; + u64 skb_mstamp; + }; +#if defined(CONFIG_BCM_KF_NBUFF) + __u32 unused; + union { + /* 3 bytes unused */ + unsigned int recycle_and_rnr_flags; + unsigned int recycle_flags; + }; + /* + * Several skb fields have been regrouped together for better data locality + * cache performance, 16byte cache line proximity. + * In 32 bit architecture, we have 32 bytes of data before this comment. + * In 64 bit architecture, we have 52 bytes of data at this point. + */ + + /*--- members common to fkbuff: begin here ---*/ + struct { + union { + /* see fkb_in_skb_test() */ + void *fkbInSkb; + void *word0; + }; + + /* defined(CONFIG_BLOG), use blog_ptr() */ + struct blog_t *blog_p; + unsigned char *data; + + /* The len in fkb is only 24 bits other 8 bits are used as internal flags + * when fkbInSkb is used the max len can be only 24 bits, the bits 31-24 + * are cleared + * currently we don't have a case where len can be >24 bits. + */ + union { + unsigned int len; + /* used for fkb_in_skb test */ + __u32 len_word; + }; + + union { + __u32 mark; + __u32 dropcount; + void *queue; + /* have to declare the following variation of fkb_mark + * for the ease of handling 64 bit vs 32 bit in fcache + */ + unsigned long fkb_mark; + __u32 fc_ctxt; /* hybrid flow cache context */ + }; + + union { + __u32 priority; + wlFlowInf_t wl; + }; + + /* Recycle preallocated skb or data */ + RecycleFuncP recycle_hook; + + union { + unsigned long recycle_context; + struct sk_buff *next_free; + __u32 fpm_num; + }; +#ifdef CONFIG_64BIT + } ____cacheline_aligned; + /* + * purposedly making the above fkbuff data structure cacheline aligned + * in 64 bit architecture. + * This can ensure the offset to the content is fixed into same cacheline. + * Main reason we only declare as cacheline_aligned for 64 bit is that + * we have manually calculated to ensure that this structure is 32 byte + * aligned in 32 bit architecture. If we add ____cacheline_aligned + * also for 32 bit architecture, it will waste 64 byte memory if that + * architecture is with 64 byte cache line size (i.e., 63148). + */ +#else + }; +#endif + /*--- members common to fkbuff: end here ---*/ + + +#endif + + struct bcm_skb_ext bcm_ext; + + union { + struct { + unsigned long _skb_refdst; + void (*destructor)(struct sk_buff *skb); + }; + struct list_head tcp_tsorted_anchor; + }; + + struct sec_path *sp; + unsigned long _nfct; + struct nf_bridge_info *nf_bridge; +#if defined(CONFIG_BCM_KF_NBUFF) + unsigned int data_len; +#else + unsigned int len, + data_len; +#endif + __u16 mac_len, + hdr_len; + + /* Following fields are _not_ copied in __copy_skb_header() + * Note that queue_mapping is here mostly to fill a hole. + */ + __u16 queue_mapping; + +/* if you move cloned around you also must adapt those constants */ +#ifdef __BIG_ENDIAN_BITFIELD +#define CLONED_MASK (1 << 7) +#else +#define CLONED_MASK 1 +#endif +#define CLONED_OFFSET() offsetof(struct sk_buff, __cloned_offset) + + __u8 __cloned_offset[0]; + __u8 cloned:1, + nohdr:1, + fclone:2, + peeked:1, + head_frag:1, + xmit_more:1, + pfmemalloc:1; + + /* fields enclosed in headers_start/headers_end are copied + * using a single memcpy() in __copy_skb_header() + */ + /* private: */ + __u32 headers_start[0]; + /* public: */ + +/* if you move pkt_type around you also must adapt those constants */ +#ifdef __BIG_ENDIAN_BITFIELD +#define PKT_TYPE_MAX (7 << 5) +#else +#define PKT_TYPE_MAX 7 +#endif +#define PKT_TYPE_OFFSET() offsetof(struct sk_buff, __pkt_type_offset) + + __u8 __pkt_type_offset[0]; + __u8 pkt_type:3; + __u8 ignore_df:1; + __u8 nf_trace:1; + __u8 ip_summed:2; + __u8 ooo_okay:1; + + __u8 l4_hash:1; + __u8 sw_hash:1; + __u8 wifi_acked_valid:1; + __u8 wifi_acked:1; + __u8 no_fcs:1; + /* Indicates the inner headers are valid in the skbuff. */ + __u8 encapsulation:1; + __u8 encap_hdr_csum:1; + __u8 csum_valid:1; + + __u8 csum_complete_sw:1; + __u8 csum_level:2; + __u8 csum_not_inet:1; + __u8 dst_pending_confirm:1; + __u8 ndisc_nodetype:2; + __u8 ipvs_property:1; + + __u8 inner_protocol_type:1; + __u8 remcsum_offload:1; + __u8 offload_fwd_mark:1; + __u8 offload_mr_fwd_mark:1; + __u8 tc_skip_classify:1; + __u8 tc_at_ingress:1; + __u8 tc_redirected:1; + __u8 tc_from_ingress:1; + __u8 decrypted:1; + __u16 tc_index; /* traffic control index */ + + union { + __wsum csum; + struct { + __u16 csum_start; + __u16 csum_offset; + }; + }; +#ifdef CONFIG_BCM_KF_NBUFF +#else + __u32 priority; +#endif + int skb_iif; + __u32 hash; + __be16 vlan_proto; + __u16 vlan_tci; + union { + unsigned int napi_id; + unsigned int sender_cpu; + }; + __u32 secmark; + +#if defined(CONFIG_BCM_KF_NBUFF) + __u32 reserved_tailroom; +#else + union { + __u32 mark; + __u32 reserved_tailroom; + }; +#endif + + union { + __be16 inner_protocol; + __u8 inner_ipproto; + }; + + __u16 inner_transport_header; + __u16 inner_network_header; + __u16 inner_mac_header; + + __be16 protocol; + __u16 transport_header; + __u16 network_header; + __u16 mac_header; + + /* private: */ + __u32 headers_end[0]; + + /* + * This is the control buffer. It is free to use for every + * layer. Please put your private variables there. If you + * want to keep them across layers you have to do a skb_clone() + * first. This is owned by whoever has the skb queued ATM. + */ + char cb[BCM_SKB_CB_SIZE] __aligned(8); + +/* + * ------------------------------- CAUTION!!! --------------------------------- + * Do NOT add a new field or modify any existing field(except cb) before this + * line to the beginning of the struct sk_buff. Doing so will cause + * struct sk_buff to be incompatible with the compiled binaries and may cause + * the binary only modules to crash. + * --------------------------------------------------------------------------- + */ + + /* public: */ + + /* These elements must be at the end, see alloc_skb() for details. */ + sk_buff_data_t tail; + sk_buff_data_t end; +#if defined(CONFIG_BCM_KF_NBUFF) + unsigned char *head; +#else + unsigned char *head, + *data; +#endif + unsigned int truesize; + refcount_t users; +}; + + +#endif /* _BCM_SKBUFF_H */ diff --git a/include/linux/blog.h b/include/linux/blog.h new file mode 100644 index 0000000000000000000000000000000000000000..d7097ae129ae26e4fd7b24ed7d32085555cb281e --- /dev/null +++ b/include/linux/blog.h @@ -0,0 +1,3116 @@ +#if defined(CONFIG_BLOG) + +#ifndef __BLOG_H_INCLUDED__ +#define __BLOG_H_INCLUDED__ + +/*--------------------------------*/ +/* Blog.h and Blog.c for Linux OS */ +/*--------------------------------*/ + +/* +* <:copyright-BRCM:2003:DUAL/GPL:standard +* +* Copyright (c) 2003 Broadcom +* All Rights Reserved +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed +* to you under the terms of the GNU General Public License version 2 +* (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +* with the following added to such license: +* +* As a special exception, the copyright holders of this software give +* you permission to link this software with independent modules, and +* to copy and distribute the resulting executable under terms of your +* choice, provided that you also meet, for each linked independent +* module, the terms and conditions of the license of that module. +* An independent module is a module which is not derived from this +* software. The special exception does not apply to any modifications +* of the software. +* +* Not withstanding the above, under no circumstances may you combine +* this software in any way with any other Broadcom software provided +* under a license other than the GPL, without Broadcom's express prior +* written consent. +* +:> +*/ + +/* + ******************************************************************************* + * + * File Name : blog.h + * + * Description: + * + * A Blog is an extension of the native OS network stack's packet context. + * In Linux a Blog would be an extension of the Linux socket buffer (aka skbuff) + * or a network device driver level packet context FkBuff. The nbuff layer + * provides a transparent access SHIM to the underlying packet context, may it + * be a skbuff or a fkbuff. In a BSD network stack, a packet context is the + * BSD memory buffer (aka mbuff). + * + * Blog layer provides Blog clients a SHIM to the native OS network stack: + * Blog clients may be implemented to: + * - debug trace a packet as it passes through the network stack, + * - develop traffic generators (loop) at the network device driver level. + * - develop network driver level promiscuous mode bound applications and use + * the Blog SHIM to isolate themselves from the native OS network constructs + * or proprietery network constructs such as Ethernet bridges, VLAN network + * interfaces, IGMP, firewall and connection tracking systems. + * + * As such, Blog provides an extension of the packet context and contains the + * received and transmitted packets data and parsed information. Parsing results + * are saved to describe, the type of layer 1, 2, 3 and 4 headers seen, whether + * the packet was a unicast, broadcast or multicast, a tunnel 4in6 or 6in4 etc. + * + * Blog views a receive or transmit end-point to be any construct that can be + * described by a end point context and a handler op. An end-point could hence + * be a: + * - a network device (Linux net_device with hard start transmit handler), + * - a link or queue in the network stack (e.g. a Linux Traffic Control queue + * or a netlink or raw socket queue), + * - a file system logging interface and its logging handler, + * - a virtual interface to some hardware block that provides some hardware + * assisted functionality (e.g. IPSEC acceleration or checksum offloading + * or GSO block), + * - a raw interface to an external hardware test traffic generator using say + * a DMA mapped packet reception or transmission. + * + * Blog clients are hence applications that provide value added capability by + * binding at such end-points. + * + * A simple Blog client application is a loop traffic generator that simply + * acts as a sink of packets belonging to a specific "l3 flow" and mirrors + * them to another interface or loops them back into the stack by serving as a + * source to a receive network device, while measuring the packet processing + * datapath performance in the native OS network stack/proprietary constructs. + * Such a loop traffic generator could be used to inject N cells/packets + * that cycle through the system endlessly, serving as background traffic while + * a few flows are studied from say a QOS perspective. + * + * Another example of a Blog client is a proxy accelerator (hardware / software) + * that is capable of snooping on specific flows and accelerating them while + * bypassing the native OS network stack and/or proprietery constructs. It is + * however required that the native OS constructs can co-exist. E.g. it may be + * necessary to refresh a network bridge's ARL table, or a connection/session + * tracker, or update statistics, when individual packets bypass such network + * constructs. A proxy accelerator may also reside between a Rx network device + * a hardware IPSEC accelerator block and a Tx network device. + * + * Blog layer provides a logical composite SHIM to the network constructs + * Linux or proprietery, allowing 3rd party network constructs to be seemlesly + * supported in the native OS. E.g a network stack that uses a proprietery + * session tracker with firewalling capability would need to be transparently + * accessed, so that a Blog client may refresh the session tracking object when + * packets bypass the network stack. + * + * For each OS (eCOS, Linux, BSD) a blog.c implementation file is provided that + * implements the OS specific SHIM. Support for 3rd-party network constructs + * would need to be defined in the blog.c . E.g. for Linux, if a proprietery + * session tracker replaces the Linux netfilter connection tracking framework, + * then the void * ct_p and the corresponding query/set operations would need to + * be implemented. The Blog clients SHOULD NOT rely on any function other than + * those specifically defined allowing a coexistence of the Blog client and the + * native construct. In the example of a ct_p, for all practice and purposes, + * the void *, could have been a key or a handle to a connection tracking object + * + * Likewise, the Blog client may save need to save a client key with the + * network constuct. Again a client key may be a pointer to a client object or + * simply a hash key or some handle semantics. + * + * The logical SHIM is defined as follows: + * + * __doc_include_if_linux__ + * + * 1. Extension of a packet context with a logging context: + * ======================================================== + * Explicit APIs to allocate/Free a Blog structure, and bind to the packet + * context, may it be a skbuff or a fkbuff. Support for transferring a + * Blog_t structure from one packet context to another during the course of + * a packet in the network stack involving a packet context clone/copy is + * also included. The release and recycling of Blog_t structures when a + * packet context is freed are also providied. + * Binding is bi-directional: packet context <-- --> Blog_t + * + * + * 2. Associating native OS or 3rd-party network constructs: blog_link() + * ========================================================================== + * Examples of network constructs + * "dev" - Network device + * "ct" - Connection or session tracker + * "fdb" - Network bridge forwarding database entity + * + * Association is pseudo bi-directional, using "void *" binding in a Blog_t to + * a network construct. In the reverse, a network construct will link to a + * Blog client entity using a Key concept. Two types of keys are currently + * employed, a BlogFlowKey and a BlogGroupKey. + * + * A BlogFlowKey would typically refer to a single unidirectional packet + * stream defined by say all packets belonging to a unidirectional IPv4 flow, + * whereas a BlogGroupKey could be used to represent a single downstream + * multicast stream (IP multicast group) that results in replicated streams + * pertaining to multiple clients joining a the IPv4 multicast group. + * + * Likewise, one may represent a single unidirectional IPv4 UDP flow using + * BlogFlowKey, and the reverse direction IPv4 UDP reply flow + * using another BlogFlowKey, and represent the mated pair using a + * BlogGroupKey. + * + * In a Blog traffic generator client, where in several IPv4 UDP flows, each + * represented independently using a BlogFlowKey, allows for a set of them + * (background downstream stress traffic) to be managed as a group using a + * BlogGroupKey. + * + * Designer Note: + * A network construct may be required to save a BlogFlowKey and/or + * BlogGroupKey to complete the reverse binding between a network construct + * and the Blog client application. An alternate approach would be to save + * a pointer to the Blog_t in the network construct with an additional + * dereference through the keys saved within the Blog_t object. + * + * A BlogFlowKey and a BlogGroupKey is a 32bt sized unit and can serve either + * as a pointer (32bit processor) or a index or a hash key or ... + * + * + * 3. Network construct and Blog client co-existence call backs: + * ============================================================= + * + * blog_notify(): + * ============== + * A network construct may notify a Blog client of a change of status and may + * be viewed as a "downcall" from specialized network construct to a Blog client + * E.g. if a connection/session tracking system deems that a flow needs to be + * deleted or say it itself is being destroyed, then it needs to notify the Blog + * client. This would allow the Blog client to cleanup any association with the + * network construct. + * Ability for a Blog client to receive general system wide notifications of + * changes, to include, network interfaces or link state changes, protocol stack + * service access point changes, etc. + * Designer Note: Linux notification list? + * + * blog_request(): + * =============== + * A Blog client may request a change in state in the network construct and may + * be viewed as a "upcall" from the Blog client into the network construct. A + * timer refresh of the bridge fdb or connection tracking object, or a query + * whether the session tracker has successfully established (e.g. a TCP 3-way + * handshake has completed, or a IGMP client was permitted to join a group, or a + * RTSP session was successful) a uni-driectional or bi-directional flow. + * + * + * 4. Network end-point binding of Blog client + * =========================================== + * + * blog_init(), blog_sinit(), blog_finit(): + * ======================================== + * __comment_if_linux__ : This function is invoked by a Linux network device on + * packet reception to pass the packet to a Blog client application. + * + * Pass a packet context to a Blog client at a "RX" network device either using + * a skbuff or a fkbuff packet context. Blog client MAY ONLY ACCESS fkbuff + * fields. As per the nbuff specification, a FkBuff may be considered as a + * base class and a skbuff is a derived class, inheriting the base class members + * of the base class, fkbuff. The basic fields of a packet context are a pointer + * to the received packet's data, data length, a set of reserved fields to carry + * layer 1 information, queue priority, etc, and packet context and or packet + * recycling. The layer 1 information is described in terms of channels and + * and link layer phy preambles. A channel could be an ATM VCI, a DSL queue, a + * PON Gem Port. A Phy could describe the LINK layer type and or a preamble for + * instance a RFC2684 header in the DSL world. + * + * blog_[s|f]init() will setup the L1 coarse key<channel,phy> and invokes a Blog + * client's receive hook. A Blog client may consume the packet bypassing the + * native OS network stack, may suggest that the packet context be extended by + * a Blog_t structure or may deem that the packet is of not interest. As such + * the Blog client will return PKT_DONE, PKT_BLOG or PKT_NORM, respectively. In + * case no Blog client has been registered for receiving packets (promiscuous) + * driectly from RX network devices, then the packet will follow a normal data + * path within the network stack (PKT_NORM). + * + * Designer Note: Blog clients MAY NOT use fields not defined in FkBuff. + * + * + * blog_emit(): + * ============ + * __comment_if_linux__ : This function is invoked by a Linux network device + * prior to packet transmission to pass the packet to a Blog client application. + * + * Pass a packet context to a Blog client at a "TX" network device either using + * a skbuff or a fkbuff packet context. The same restrictions on a Blog client + * pertaining to packet field context access as defined in the blog_init() + * variant of APIs is applicable to blog_emit(). A Blog client may also return + * PKT_NORM or PKT_DONE, to indicate normal processing, or packet consumption. + * + * Designer Note: blog_emit() will ONLY pass those packets to Blog clients that + * have a packet context extended with a Blog_t structure. Hence skbuffs or + * fkbuffs that do not have a Blog_t extension will not be handed to the Blog + * client. Do we need blog_semit/blog_femit variants. + * + * + * 5. Binding Blog client applications: blog_bind() + * ================================================ + * blog_bind() enables a "single" client to bind into the network stack by + * specifying a network device packet reception handler, a network device packet + * transmission handler, network stack to blog client notify hook. + * + * + * 6. Miscellanous + * =============== + * - Blog_t management. + * - Data-filling a Blog_t. + * - Protocol Header specifications independent of OS. + * - Debug printing. + * + * + * __end_include_if_linux__ + * + * Version 1.0 SKB based blogging + * Version 2.0 NBuff/FKB based blogging (mbuf) + * Version 2.1 IPv6 Support + * Version 3.0 Restructuring Blog SHIM to support eCOS, Linux and proprietery + * network constructs + * + ******************************************************************************* + */ + +#define BLOG_VERSION "v3.0" + +#if defined(__KERNEL__) /* Kernel space compilation */ +#include <linux/types.h> /* LINUX ISO C99 7.18 Integer types */ +#else /* User space compilation */ +#include <stdint.h> /* C-Lib ISO C99 7.18 Integer types */ +#endif +#include <linux/blog_net.h> /* IEEE and RFC standard definitions */ +#include <linux/nbuff_types.h> /* for IS_SKBUFF_PTR */ +#include <linux/brcm_dll.h> + +#ifndef NULL_STMT +#define NULL_STMT do { /* NULL BODY */ } while (0) +#endif + +#undef BLOG_DECL +#define BLOG_DECL(x) x, + +#ifndef BLOG_OFFSETOF +#define BLOG_OFFSETOF(stype, member) ((size_t) &((struct stype *)0)->member) +#endif + +/* Forward declarations */ +struct blog_t; +typedef struct blog_t Blog_t; +#define BLOG_NULL ((Blog_t*)NULL) +#define BLOG_KEY_NONE 0 + +/* __bgn_include_if_linux__ */ + +struct sk_buff; /* linux/skbuff.h */ +struct fkbuff; /* linux/nbuff.h */ + +/* See RFC 4008 */ + + +typedef struct blogCtTimeFlags { + uint32_t unused: 31; + uint32_t valid: 1; /* BlogCtTime has valid values */ +} BlogCtTimeFlags_t; + +/* used to pass timer info between the stack and blog layer */ +typedef struct blogCtTime { + BlogCtTimeFlags_t flags; /* Flags */ + uint8_t unknown; /* unknown proto */ + uint8_t proto; /* known proto TCP, UDP */ + uint8_t intv; /* intv in sec */ + uint8_t idle; /* idle time in sec */ +} BlogCtTime_t; + +/* used to exchange info between fcache and drivers */ +typedef struct { + uint32_t h_proto; /* protocol */ + uint32_t key_match; /* key */ + void *txdev_p; + uint8_t tx_l3_offset; + uint8_t tx_l4_offset; + uint8_t mcast_fwd_exception; /* Runner mcast forwarding exception */ + uint8_t esp_ivsize; + uint8_t esp_icvsize; +} BlogFcArgs_t; + +typedef struct { + uint64_t rx_packets; + uint64_t rx_bytes; + int32_t rx_rtp_packets_lost; /*TODO chekc why this is defined as signed int */ + uint32_t pollTS_ms; // Poll timestamp in ms +}BlogFcStats_t; + +typedef struct { + u64 packet_count; + u64 byte_count; +} blog_fast_stats_t; + +/* + * Linux Netfilter Conntrack registers it's conntrack refresh function which + * will be invoked to refresh a conntrack when packets belonging to a flow + * managed by Linux conntrack are bypassed by a Blog client. + */ +typedef void (*blog_cttime_upd_t)(void * ct_p, BlogCtTime_t *ct_time_p); +extern blog_cttime_upd_t blog_cttime_update_fn; + + +extern int blog_ct_get_stats(const void *ct, uint32_t blog_key, uint32_t dir, + BlogFcStats_t *stats); +extern int blog_ct_push_stats(void); + +#if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE) +typedef int (*blog_gre_rcv_check_t)(void *dev, BlogIpv4Hdr_t *iph, uint16_t len, + void **tunl_pp, uint32_t *pkt_seqno_p); +extern blog_gre_rcv_check_t blog_gre_rcv_check_fn; + +typedef int (*blog_gre_xmit_upd_t)(void * tunl_p, BlogIpv4Hdr_t *iph, uint16_t len); +extern blog_gre_xmit_upd_t blog_gre_xmit_update_fn; +typedef int (*blog_gre6_rcv_check_t)(void *dev, BlogIpv6Hdr_t *ipv6h, uint16_t len, + void **tunl_pp, uint32_t *pkt_seqno_p); +extern blog_gre6_rcv_check_t blog_gre6_rcv_check_fn; + +typedef int (*blog_gre6_xmit_upd_t)(void * tunl_p, BlogIpv6Hdr_t *ipv6h, uint16_t len); +extern blog_gre6_xmit_upd_t blog_gre6_xmit_update_fn; +#endif + + +#define PPTP_NOT_ACK 0 +#define PPTP_WITH_ACK 1 +#define PPTP_GRE_VER_0 0 +#define PPTP_GRE_VER_1 1 +#define PPTP_GRE_NONE 2 + +typedef int (*blog_pptp_xmit_upd_t)(uint16_t call_id, uint32_t seqNum, + uint32_t ackNum, uint32_t daddr); +extern blog_pptp_xmit_upd_t blog_pptp_xmit_update_fn; + +typedef int (*blog_pptp_xmit_get_t)(uint16_t call_id, uint32_t* seqNum, + uint32_t* ackNum, uint32_t daddr); +extern blog_pptp_xmit_get_t blog_pptp_xmit_get_fn; + +typedef int (*blog_pptp_rcv_check_t)(uint16_t call_id, uint32_t *rcv_pktSeq, + uint32_t rcv_pktAck, uint32_t saddr); +extern blog_pptp_rcv_check_t blog_pptp_rcv_check_fn; + +typedef int (*blog_l2tp_rcv_check_t)(void *dev, uint16_t tunnel_id, + uint16_t session_id); +extern blog_l2tp_rcv_check_t blog_l2tp_rcv_check_fn; + +#if defined(CONFIG_BCM_OVS) +typedef int (* blog_is_ovs_internal_dev_t)(void *dev); +typedef unsigned long (* blog_mega_get_key_t)(void *mega); +typedef void (* blog_mega_set_key_t)(void *mega, unsigned long blog_key); +typedef void (* blog_mega_put_fast_stats_t)(void *net_p, + const blog_fast_stats_t *stats); + +typedef struct { + blog_is_ovs_internal_dev_t is_ovs_internal_dev; + blog_mega_get_key_t mega_get_key; + blog_mega_set_key_t mega_set_key; + blog_mega_put_fast_stats_t mega_put_fast_stats; +} blog_ovs_hooks_t; +void blog_bind_ovs(blog_ovs_hooks_t *blog_ovs_hooks_p); +#endif + +/* __end_include_if_linux__ */ + + + +/* + *------------------------------------------------------------------------------ + * Denotes a Blog client, + *------------------------------------------------------------------------------ + */ +typedef enum { + BLOG_DECL(BlogClient_fcache) + BLOG_DECL(BlogClient_mcast) + BLOG_DECL(BlogClient_MAX) +} BlogClient_t; + +/* + *------------------------------------------------------------------------------ + * Denotes whether a packet is consumed and freed by a Blog client application, + * whether a packet needs to be processed normally within the network stack or + * whether a packet context is extended with a Blog_t object. + *------------------------------------------------------------------------------ + */ +typedef enum { + BLOG_DECL(PKT_DONE) /* Packet consumed and freed */ + BLOG_DECL(PKT_NORM) /* Continue normal stack processing */ + BLOG_DECL(PKT_BLOG) /* Continue stack with blogging */ + BLOG_DECL(PKT_DROP) /* Drop Packet */ + BLOG_DECL(PKT_TCP4_LOCAL) /* ipv4 tcp packet terminating locally*/ + BLOG_DECL(BLOG_ACTION_MAX) +} BlogAction_t; + +/* + *------------------------------------------------------------------------------ + * Denotes the direction in the network stack when a packet is processed by a + * virtual network interface/network device. + *------------------------------------------------------------------------------ + */ +typedef enum { + BLOG_DECL(DIR_RX) /* Receive path in network stack */ + BLOG_DECL(DIR_TX) /* Transmit path in network stack */ + BLOG_DECL(BLOG_DIR_MAX) +} BlogDir_t; + +/* + *------------------------------------------------------------------------------ + * Denotes the type of Network entity associated with a Blog_t. + * + * BlogNetEntity_t may be linked to a blog using blog_link to make the Blog_t + * point to the BlogNetEntity_t. A reverse linking from the BlogNetEntity_t to + * Blog_t is only possible via a key (if necessary when a one to one association + * between the BlogNetEntity_t and a Blog exists. For instance, there is a + * one to one association between a Flow Connection Tracker and a Blog. In fact + * a Linux Netfilter Connection Tracking object manages a bi-directional flow + * and thus may have 2 keys to reference the corresponding Blog_t. However, a + * network device (physical end device or a virtual device) may have multiple + * Flows passing through it and hence no one-to-one association exists. In this + * can a Blog may have a link to a network device, but the reverse link (via a + * key) is not saved in the network device. + * + * Linking a BlogNetEntity_t to a blog is done via blog_link() whereas saving + * a reference key into a BlogNetEntity_t is done via blog_request() by the + * Blog client application, if needed. + * + *------------------------------------------------------------------------------ + */ + +#define BLOG_CT_PLD 0U +#define BLOG_CT_DEL 1U +#define BLOG_CT_MAX 2U + +/* FLOWTRACK: param1 is ORIG=0 or REPLY=1 direction */ +#define BLOG_PARAM1_DIR_ORIG 0U +#define BLOG_PARAM1_DIR_REPLY 1U +#define BLOG_PARAM1_DIR_MAX 2U + +/* FLOWTRACK: param2 is IPv4=0, IPv6=1, GRE=2, L2TP=3 */ +#define BLOG_PARAM2_IPV4 0U +#define BLOG_PARAM2_IPV6 1U +#define BLOG_PARAM2_GRE_IPV4 2U +#define BLOG_PARAM2_L2TP_IPV4 3U +#define BLOG_PARAM2_MAX 4U +#define BLOG_CT_VER_MAX 2U + +/* MAP_TUPLE: param1 is US=0 or DS=1 direction */ +#define BLOG_PARAM1_MAP_DIR_US BLOG_PARAM1_DIR_ORIG +#define BLOG_PARAM1_MAP_DIR_DS BLOG_PARAM1_DIR_REPLY + +/* BRIDGEFDB: param1 is src|dst */ +#define BLOG_PARAM1_SRCFDB 0U +#define BLOG_PARAM1_DSTFDB 1U + +/* LLID/GEM index for the mcast data received at WAN side. 0xFE means any value is acceptable */ +#define BLOG_CHAN_XPON_MCAST_ANY 0xFE + +/* IF_DEVICE: param1 is direction RX or TX, param 2 is minMtu */ + +typedef enum { + BLOG_DECL(FLOWTRACK) /* Flow (connection|session) tracker */ + BLOG_DECL(BRIDGEFDB) /* Bridge Forwarding Database entity */ + BLOG_DECL(MCAST_FDB) /* Multicast Client FDB entity */ + BLOG_DECL(IF_DEVICE) /* Virtual Interface (network device) */ + BLOG_DECL(IF_DEVICE_MCAST) /* Virtual Interface (network device) */ + BLOG_DECL(GRE_TUNL) /* GRE Tunnel */ + BLOG_DECL(TOS_MODE) /* TOS_MODE */ + BLOG_DECL(MAP_TUPLE) /* Flow (MAP-T connection) tracker */ + BLOG_DECL(MEGA) /* Megaflow tracker */ + BLOG_DECL(BLOG_NET_ENTITY_MAX) +} BlogNetEntity_t; + +/* + *------------------------------------------------------------------------------ + * Denotes a type of notification sent from the network stack to the Blog client + * See blog_notify(BlogNotify_t, void *, unsigned long param1, uint32_t param2); + *------------------------------------------------------------------------------ + */ + +/* MCAST_CONTROL_EVT: param1 is add|del, and param2 is IPv4|IPv6 */ +#define BLOG_PARAM1_MCAST_ADD 0U +#define BLOG_PARAM1_MCAST_DEL 1U +#define BLOG_PARAM2_MCAST_IPV4 0U +#define BLOG_PARAM2_MCAST_IPV6 1U + +/* LINK_STATE_CHANGE: param1 */ +#define BLOG_PARAM1_LINK_STATE_UP 0U +#define BLOG_PARAM1_LINK_STATE_DOWN 1U + +typedef enum { + BLOG_DECL(DESTROY_FLOWTRACK) /* Session/connection is deleted */ + BLOG_DECL(DESTROY_BRIDGEFDB) /* Bridge FDB has aged */ + BLOG_DECL(MCAST_CONTROL_EVT) /* Mcast client joins a group event */ + BLOG_DECL(MCAST_SYNC_EVT) /* Topology change for mcast event */ + BLOG_DECL(DESTROY_NETDEVICE) /* Network device going down */ + BLOG_DECL(FETCH_NETIF_STATS) /* Fetch accumulated stats */ + BLOG_DECL(CLEAR_NETIF_STATS) /* Clear accumulated stats */ + BLOG_DECL(DYNAMIC_DSCP_EVENT) /* Dynamic DSCP change event */ + BLOG_DECL(UPDATE_NETDEVICE) /* Netdevice has been modified (MTU, etc) */ + BLOG_DECL(ARP_BIND_CHG) /* ARP IP/MAC binding change event */ + BLOG_DECL(CONFIG_CHANGE) /* Certain configuration change event */ + BLOG_DECL(UP_NETDEVICE) /* network device up */ + BLOG_DECL(DN_NETDEVICE) /* network device down */ + BLOG_DECL(CHANGE_ADDR) /* network device change MAC addr */ + BLOG_DECL(SET_DPI_PARAM) /* Set the DPI parameters */ + BLOG_DECL(DESTROY_MAP_TUPLE) /* MAPT Session/connection is deleted */ + BLOG_DECL(FLUSH) /* Flush flows based on parameters */ + BLOG_DECL(DESTROY_MEGA) /* Megaflow connection is deleted */ + BLOG_DECL(FETCH_MEGA_STATS) /* Fetch megaflow fast stats */ + BLOG_DECL(CLEAR_MEGA_STATS) /* Clear megaflow fast stats */ + BLOG_DECL(UPDATE_FLOWTRACK_IDLE_TIMEOUT)/* update idle timeout */ + BLOG_DECL(BLOG_NOTIFY_MAX) +} BlogNotify_t; + +typedef enum { + BLOG_DECL(QUERY_FLOWTRACK) /* Session/connection time is queried */ + BLOG_DECL(QUERY_BRIDGEFDB) /* Bridge FDB time is queried */ + BLOG_DECL(QUERY_MAP_TUPLE) /* MAP-T connection time is queried */ + BLOG_DECL(QUERY_FLOWTRACK_STATS)/* get stats of flows associated with NPE */ + BLOG_DECL(QUERY_GET_HW_ACCEL) + BLOG_DECL(BLOG_QUERY_MAX) +} BlogQuery_t; + +typedef struct{ + int orig_queue; /* Originating queue index */ + int reply_queue; /* Reply queue index */ + int priority; /* Traffic priority */ +}BlogDpiParams_t; + + +/* Blog Notify FLUSH strucutre */ +typedef int (* BlogFlushMetadataFunc_t)(void *metadata_p, const Blog_t *const blog_p); + +typedef struct { + uint32_t flush_all :1; + uint32_t flush_flow :1; + uint32_t flush_dev :1; + uint32_t flush_dstmac :1; + uint32_t flush_srcmac :1; + uint32_t flush_meta :1; /* Not available through Userspace/CLI */ + uint32_t flush_hw :1; /* Flush all flows from HW */ + uint32_t flush_unused :25; + uint8_t mac[6]; + int devid; + int flowid; + void *metadata_p; /* flush_meta = 1 ; Must set metadata_p, devid & flush_dev */ + BlogFlushMetadataFunc_t func_p; /* flush_meta = 1 ; Must provide callback func */ +}BlogFlushParams_t; + +/* + *------------------------------------------------------------------------------ + * Denotes a type of request from a Blog client to a network stack entity. + *------------------------------------------------------------------------------ + */ + +typedef enum { + BLOG_DECL(FLOWTRACK_KEY_SET) /* Set Client key into Flowtracker */ + BLOG_DECL(FLOWTRACK_KEY_GET) /* Get Client key into Flowtracker */ + BLOG_DECL(FLOWTRACK_DSCP_GET) /* Get DSCP from Flow tracker:DYNDSCP */ + BLOG_DECL(FLOWTRACK_CONFIRMED) /* Test whether session is confirmed */ + BLOG_DECL(FLOWTRACK_ALG_HELPER) /* Test whether flow has an ALG */ + BLOG_DECL(FLOWTRACK_EXCLUDE) /* Clear flow candidacy by Client */ + BLOG_DECL(FLOWTRACK_TIME_SET) /* Set time in a flow tracker */ + BLOG_DECL(FLOWTRACK_IDLE_TIMEOUT_GET) /* get idle timeout in a flow tracker */ + BLOG_DECL(FLOWTRACK_PUT_STATS) /* Push accumulated stats to conntrack*/ + BLOG_DECL(NETIF_PUT_STATS) /* Push accumulated stats to devices */ + BLOG_DECL(LINK_XMIT_FN) /* Fetch device link transmit function*/ + BLOG_DECL(LINK_NOCARRIER) /* Fetch device link carrier */ + BLOG_DECL(NETDEV_NAME) /* Network device name */ + BLOG_DECL(MCAST_DFLT_MIPS) /* Delete action in blogRule chain */ + BLOG_DECL(IQPRIO_SKBMARK_SET) /* Set IQOS Prio in skb->mark */ + BLOG_DECL(DPIQ_SKBMARK_SET) /* Set DPIQ in skb->mark */ + BLOG_DECL(BRIDGEFDB_KEY_SET) /* Set Client key into bridge FDB */ + BLOG_DECL(BRIDGEFDB_KEY_GET) /* Get Client key into bridge FDB */ + BLOG_DECL(BRIDGEFDB_TIME_SET) /* Refresh bridge FDB time */ + BLOG_DECL(SYS_TIME_GET) /* Get the system time in jiffies */ + BLOG_DECL(GRE_TUNL_XMIT) /* GRE Tunnel tx */ + BLOG_DECL(GRE6_TUNL_XMIT) /* GRE6 Tunnel tx */ + BLOG_DECL(SKB_DST_ENTRY_SET) /* get dst_entry from skb */ + BLOG_DECL(SKB_DST_ENTRY_RELEASE)/* release dst_entry from blog */ + BLOG_DECL(NETDEV_ADDR) /* Device MAC addr */ + BLOG_DECL(FLOW_EVENT_ACTIVATE) /* Flow Activation event */ + BLOG_DECL(FLOW_EVENT_DEACTIVATE)/* Flow Deactivation event */ + BLOG_DECL(CHK_HOST_DEV_MAC) /* Check Dev HostMAC for addition */ + BLOG_DECL(MAP_TUPLE_KEY_SET) /* Set Client key into MAPT Tuple */ + BLOG_DECL(MAP_TUPLE_KEY_GET) /* Get Client key into MAPT Tuple */ + BLOG_DECL(MEGA_KEY_SET) /* Set Client key into megaflow */ + BLOG_DECL(MEGA_KEY_GET) /* Get Client key into megaflow */ + BLOG_DECL(MEGA_PUT_STATS) /* Put the stats in a megaflow */ + BLOG_DECL(BLOG_REQUEST_MAX) +} BlogRequest_t; + +/* + *------------------------------------------------------------------------------ + * Denotes a type of update to an existing Blog flow. + *------------------------------------------------------------------------------ + */ + +typedef enum { + BLOG_DECL(BLOG_UPDATE_DPI_QUEUE) /* DPI Queue assignment has changed */ + BLOG_DECL(BLOG_UPDATE_DPI_PRIORITY) /* DPI Priority assignment has changed */ + BLOG_DECL(BLOG_UPDATE_BITMAP) /* Multicast client bitmap has changed */ + BLOG_DECL(BLOG_UPDATE_FWD_AND_TRAP) /* fwd_and_trap bit has changed */ + BLOG_DECL(BLOG_UPDATE_BITMAP_FWD_AND_TRAP) /* Mcast client bitmap and + fwd_and_trap bit have changed */ + BLOG_DECL(BLOG_UPDATE_MAX) +} BlogUpdate_t; + +/* + *------------------------------------------------------------------------------ + * Flow event parameters + *------------------------------------------------------------------------------ + */ + +typedef enum { + BLOG_DECL(FLOW_EVENT_TYPE_FC) /* FCache Flow */ + BLOG_DECL(FLOW_EVENT_TYPE_HW) /* Hardware Flow */ + BLOG_DECL(FLOW_EVENT_TYPE_MAX) +} BlogFlowEventType_t; + + +typedef struct { + void *ct_pld_p; + void *ct_del_p; + union { + struct { + uint32_t is_downstream :1; + uint32_t flow_event_type :2; + uint32_t reserved :21; + uint32_t skb_mark_flow_id :8; + }; + uint32_t u32; + }; +} BlogFlowEventInfo_t; + + +/* + *------------------------------------------------------------------------------ + * Clean this up. + *------------------------------------------------------------------------------ + */ + +#define BLOG_ENCAP_MAX 6 /* Maximum number of L2 encaps */ +#define BLOG_HDRSZ_MAX 38 /* Maximum size of L2 encaps */ + +typedef enum { + BLOG_DECL(GRE_ETH) /* e.g. BLOG_XTMPHY, BLOG_GPONPHY */ + BLOG_DECL(BCM_XPHY) /* e.g. BLOG_XTMPHY, BLOG_GPONPHY */ + BLOG_DECL(BCM_SWC) /* BRCM LAN Switch Tag/Header */ + BLOG_DECL(ETH_802x) /* Ethernet */ + BLOG_DECL(VLAN_8021Q) /* Vlan 8021Q (incld stacked) */ + BLOG_DECL(PPPoE_2516) /* PPPoE RFC 2516 */ + BLOG_DECL(PPP_1661) /* PPP RFC 1661 */ + BLOG_DECL(PLD_IPv4) /* Payload IPv4 */ + BLOG_DECL(PLD_IPv6) /* Payload IPv6 */ + BLOG_DECL(PPTP) /* PPTP Header */ + BLOG_DECL(L2TP) /* L2TP Header */ + BLOG_DECL(GRE) /* GRE Header */ + BLOG_DECL(ESP) /* ESP Header */ + BLOG_DECL(DEL_IPv4) /* Outer IPv4 */ + BLOG_DECL(DEL_IPv6) /* Outer IPv6 */ + BLOG_DECL(DEL_L2) /* L2 DEL */ + BLOG_DECL(PLD_L2) /* L2 PLD */ + BLOG_DECL(HDR0_IPv4) /* IPv4 Inner Header 0 */ + BLOG_DECL(HDR0_IPv6) /* IPv6 Inner Header 0 */ + BLOG_DECL(HDR0_L2) /* L2 Inner Header 0 */ + BLOG_DECL(GREoESP_type) /* GRE over ESP type */ + BLOG_DECL(GREoESP_type_resvd) /* GRE over ESP type */ + BLOG_DECL(GREoESP) /* GRE over ESP */ + BLOG_DECL(NPT6) /* NPT6 */ + BLOG_DECL(PASS_THRU) /* pass-through */ + BLOG_DECL(DEL_DST_OPTS) /* Delivery IPv6 Dest options */ + BLOG_DECL(PLD_DST_OPTS) /* Payload IPv6 Dest options */ + BLOG_DECL(LLC_SNAP) /* LLC_SNAP */ + BLOG_DECL(VXLAN) /* VXLAN Header */ + BLOG_DECL(unused) /* unused */ + BLOG_DECL(PROTO_MAX) +} BlogEncap_t; + + + + + + +/* CAUTION: Following macros have binary dependencies. Please do not change these + macros without consulting with Broadcom or the subsystem owners + Macro definition START */ +#define BLOG_IS_HWACC_DISABLED_WLAN_EXTRAPHY(rxphy,txphy) ((rxphy == BLOG_EXTRA1PHY) || \ + (txphy == BLOG_EXTRA1PHY)) +#define BLOG_IS_TX_HWACC_ENABLED_WLAN_PHY(txphy) (txphy == BLOG_WLANPHY) +/* Macro definition END */ + +/* + *------------------------------------------------------------------------------ + * Logging of a maximum 4 "virtual" network devices that a flow can traverse. + * Virtual devices are interfaces that do not perform the actual DMA transfer. + * E.g. an ATM interface would be referred to as a physical interface whereas + * a ppp interface would be referred to as a Virtual interface. + *------------------------------------------------------------------------------ + */ +#define MAX_VIRT_DEV 7 + +#define DEV_DIR_MASK 0x3ul +#define DEV_PTR_MASK (~DEV_DIR_MASK) +#define DEV_DIR(ptr) ((uintptr_t)(ptr) & DEV_DIR_MASK) + +#define IS_RX_DIR(ptr) ( DEV_DIR(ptr) == DIR_RX ) +#define IS_TX_DIR(ptr) ( DEV_DIR(ptr) == DIR_TX ) + +/* + *------------------------------------------------------------------------------ + * Device pointer conversion between with and without embeded direction info + *------------------------------------------------------------------------------ + */ +#define DEVP_APPEND_DIR(ptr,dir) ((void *)((uintptr_t)(ptr) | (uintptr_t)(dir))) +#define DEVP_DETACH_DIR(ptr) ((void *)((uintptr_t)(ptr) & (uintptr_t) \ + DEV_PTR_MASK)) +/* + *------------------------------------------------------------------------------ + * Denotes the tos mode. + *------------------------------------------------------------------------------ + */ +typedef enum { + BLOG_DECL(BLOG_TOS_FIXED) + BLOG_DECL(BLOG_TOS_INHERIT) + BLOG_DECL(BLOG_TOS_MAX) +} BlogTos_t; + +/* + *------------------------------------------------------------------------------ + * Blog statistics structure + *------------------------------------------------------------------------------ + */ +typedef struct{ + /* NOTE : All these structure variables should be of same type/size */ + + uint64_t rx_packets; /* total blog packets received */ + uint64_t tx_packets; /* total blog packets transmitted */ + uint64_t rx_bytes; /* total blog bytes received */ + uint64_t tx_bytes; /* total blog bytes transmitted */ + uint64_t multicast; /* total blog multicast packets */ + uint64_t tx_multicast_packets; /* multicast packets transmitted */ + uint64_t rx_multicast_bytes; /* multicast bytes recieved */ + uint64_t tx_multicast_bytes; /* multicast bytes transmitted */ +} BlogStats_t; + +typedef enum { + BLOG_DECL(blog_skip_reason_unknown = 0) /* unknown or customer defined */ + BLOG_DECL(blog_skip_reason_br_flood) + BLOG_DECL(blog_skip_reason_ct_tcp_state_not_est) + BLOG_DECL(blog_skip_reason_ct_tcp_state_ignore) + BLOG_DECL(blog_skip_reason_ct_status_donot_blog) + BLOG_DECL(blog_skip_reason_nf_xt_skiplog) + BLOG_DECL(blog_skip_reason_nf_ebt_skiplog) + BLOG_DECL(blog_skip_reason_scrub_pkt) + BLOG_DECL(blog_skip_reason_sch_htb) + BLOG_DECL(blog_skip_reason_sch_dsmark) + BLOG_DECL(blog_skip_reason_unknown_proto) + BLOG_DECL(blog_skip_reason_unknown_proto_ah4) + BLOG_DECL(blog_skip_reason_unknown_proto_ah6) + BLOG_DECL(blog_skip_reason_unknown_proto_esp6) + BLOG_DECL(blog_skip_reason_esp4_crypto_algo) + BLOG_DECL(blog_skip_reason_esp4_spu_disabled) + BLOG_DECL(blog_skip_reason_spudd_check_failure) + BLOG_DECL(blog_skip_reason_dpi) + BLOG_DECL(blog_skip_reason_bond) + BLOG_DECL(blog_skip_reason_map_tcp) + BLOG_DECL(blog_skip_reason_blog) + BLOG_DECL(blog_skip_reason_l2_local_termination) + BLOG_DECL(blog_skip_reason_mega_multi_output_ports) + BLOG_DECL(blog_skip_reason_mega_attr_mismatch) + BLOG_DECL(blog_skip_reason_mega_field_mismatch) + BLOG_DECL(blog_skip_reason_max) +} blog_skip_reason_t; + +typedef enum { + BLOG_DECL(blog_free_reason_unknown = 0) /* unknown or customer defined */ + BLOG_DECL(blog_free_reason_blog_emit) + BLOG_DECL(blog_free_reason_blog_iq_prio) + BLOG_DECL(blog_free_reason_kfree) + BLOG_DECL(blog_free_reason_ipmr_local) + BLOG_DECL(blog_free_reason_max) +} blog_free_reason_t; + +typedef struct { + uint32_t blog_get; + uint32_t blog_put; + uint32_t blog_skip; + uint32_t blog_free; + uint32_t blog_xfer; + uint32_t blog_clone; + uint32_t blog_copy; + uint32_t blog_min_avail; +} blog_info_stats_t; + +#define BLOG_DUMP_DISABLE 0 +#define BLOG_DUMP_RXBLOG 1 +#define BLOG_DUMP_TXBLOG 2 +#define BLOG_DUMP_RXTXBLOG 3 + +/* + * ----------------------------------------------------------------------------- + * Support accleration of L2, L3 packets. + * + * When acceleration support is enabled system wide, the default to be used may + * be set in CC_BLOG_SUPPORT_ACCEL_MODE which gets saved in blog_support_accel_mode_g. + * One may change the default (at runtime) by invoking blog_support_accel_mode(). + * ----------------------------------------------------------------------------- + */ + + +/* + * ----------------------------------------------------------------------------- + * Acceleration support: + * All the platforms support L3 tuple based acceleatiion. + * When the acceleation mode is configured as L23, the accelerators decides + * on per packet basis whether to use L2 or L3 tuple based acceleration. + * ----------------------------------------------------------------------------- + */ +#define BLOG_ACCEL_MODE_L3 0 /* Legacy. All platforms support*/ +#define BLOG_ACCEL_MODE_L23 1 /* Platforms supporting both */ + +#define CC_BLOG_SUPPORT_ACCEL_MODE (BLOG_ACCEL_MODE_L3) + +extern int blog_support_accel_mode_g; + +typedef int (*blog_accel_mode_set_t)(uint32_t accel_mode); +extern blog_accel_mode_set_t blog_accel_mode_set_fn; + +extern void blog_support_accel_mode(int accel_mode); +extern int blog_support_get_accel_mode(void); + +extern int blog_support_tcp_ack_mflows_g; + +typedef int (*blog_tcp_ack_mflows_set_t)(int enable); +extern blog_tcp_ack_mflows_set_t blog_tcp_ack_mflows_set_fn; + +extern void blog_support_set_tcp_ack_mflows(int enable); +extern int blog_support_get_tcp_ack_mflows(void); + +/* + * ----------------------------------------------------------------------------- + * Support blogging of multicast packets. + * + * When Multicast support is enabled system wide, the default to be used may + * be set in CC_BLOG_SUPPORT_MCAST which gets saved in blog_support_mcast_g. + * One may change the default (at runtime) by invoking blog_support_mcast(). + * ----------------------------------------------------------------------------- + */ + +/* Multicast Support for IPv4 and IPv6 Control */ +#define BLOG_MCAST_DISABLE 0 +#define BLOG_MCAST_IPV4 1 +#define BLOG_MCAST_IPV6 2 + +#ifdef CONFIG_BLOG_MCAST +#define CC_BLOG_SUPPORT_MCAST BLOG_MCAST_IPV4 + BLOG_MCAST_IPV6 +#else +#define CC_BLOG_SUPPORT_MCAST BLOG_MCAST_DISABLE +#endif + +extern int blog_support_mcast_g; +extern void blog_support_mcast(int enable); + +#define BCM_WLAN_PER_CLIENT_FLOW_LEARNING 1 + +/* + * ----------------------------------------------------------------------------- + * Support blogging of IPv6 traffic + * + * When IPv6 support is enabled system wide, the default to be used may + * be set in CC_BLOG_SUPPORT_IPV6 which gets saved in blog_support_ipv6_g. + * One may change the default (at runtime) by invoking blog_support_ipv6(). + * ----------------------------------------------------------------------------- + */ + +/* IPv6 Support Control: see blog_support_ipv6_g and blog_support_ipv6() */ +#define BLOG_IPV6_DISABLE 0 +#define BLOG_IPV6_ENABLE 1 + +#ifdef CONFIG_BLOG_IPV6 +#define CC_BLOG_SUPPORT_IPV6 BLOG_IPV6_ENABLE +#else +#define CC_BLOG_SUPPORT_IPV6 BLOG_IPV6_DISABLE +#endif + +extern int blog_support_ipv6_g; +extern void blog_support_ipv6(int enable); + +/* + * ----------------------------------------------------------------------------- + * Support blogging of 6rd tos + * + * When 6rd is configured, the default to be used may be set in + * CC_BLOG_DEFAULT_TUNL_TOS which gets saved in blog_tunl_tos_g. + * One may change the default (at runtime) by invoking blog_tunl_tos(). + * ----------------------------------------------------------------------------- + */ + +/* GRE Support: enable/disable */ +#define BLOG_GRE_DISABLE 0 +#define BLOG_GRE_ENABLE 1 + +#ifdef CONFIG_BLOG_GRE +#define CC_BLOG_SUPPORT_GRE BLOG_GRE_ENABLE +#else +#define CC_BLOG_SUPPORT_GRE BLOG_GRE_DISABLE +#endif + +extern int blog_gre_tunnel_accelerated_g; +extern int blog_support_gre_g; +extern void blog_support_gre(int enable); + +/* L2TP Support */ +#define BLOG_L2TP_DISABLE 0 +#define BLOG_L2TP_ENABLE 1 + +#ifdef CONFIG_BLOG_L2TP +#define CC_BLOG_SUPPORT_L2TP BLOG_L2TP_ENABLE +#else +#define CC_BLOG_SUPPORT_L2TP BLOG_L2TP_DISABLE +#endif + +extern int blog_l2tp_tunnel_accelerated_g; +extern int blog_support_l2tp_g; +extern void blog_support_l2tp(int enable); + +/* ESP Support: tunnel and pass-thru modes */ +#define BLOG_ESP_DISABLE 0 +#define BLOG_ESP_TUNNEL 1 +#define BLOG_ESP_PASS_THRU 2 + +#ifdef CONFIG_BLOG_ESP +#define CC_BLOG_SUPPORT_ESP BLOG_ESP_TUNNEL +#else +#define CC_BLOG_SUPPORT_ESP BLOG_ESP_DISABLE +#endif + +/* + * ----------------------------------------------------------------------------- + * Support 4o6 fragmentation enable/disable + * ----------------------------------------------------------------------------- + */ +#define BLOG_4O6_FRAG_DISABLE 0 +#define BLOG_4O6_FRAG_ENABLE 1 + +extern int blog_support_4o6_frag_g; +extern void blog_support_4o6_frag(int enable); + +/* blog notify processing mode */ +typedef enum { + BLOG_DECL(BLOG_NOTIFY_PROC_MODE_NOW) /* processing mode: now/sync */ + BLOG_DECL(BLOG_NOTIFY_PROC_MODE_HYBRID)/* mode: now+deferred */ + BLOG_DECL(BLOG_NOTIFY_PROC_MODE_DFRD)/* processing mode: deferred */ + BLOG_DECL(BLOG_NOTIFY_PROC_MODE_MAX) +} blog_notify_proc_mode_t; + +extern int blog_notify_proc_mode_g; +extern void blog_set_notify_proc_mode(int mode); + +typedef enum { + BLOG_DECL(BLOG_NOTIFY_API_SYNC) /* blog_notify() */ + BLOG_DECL(BLOG_NOTIFY_API_ASYNC)/* blog_notify_async() */ + BLOG_DECL(BLOG_NOTIFY_API_MAX) +} blog_notify_api_t; + +typedef enum +{ + BLOG_DECL(BLOG_NOTIFY_EVT_NONE) + BLOG_DECL(BLOG_NOTIFY_EVT_FLUSH_FDB) + BLOG_DECL(BLOG_NOTIFY_EVT_FLUSH_NPE) + BLOG_DECL(BLOG_NOTIFY_EVT_FLUSH_ARP) + BLOG_DECL(BLOG_NOTIFY_EVT_FLUSH) + BLOG_DECL(BLOG_NOTIFY_EVT_FLUSH_HW) + BLOG_DECL(BLOG_NOTIFY_EVT_FLUSH_DEV) + BLOG_DECL(BLOG_NOTIFY_EVT_FLUSH_PARAMS) + BLOG_DECL(BLOG_NOTIFY_EVT_FETCH_NETIF_STATS) + BLOG_DECL(BLOG_NOTIFY_EVT_CLEAR_NETIF_STATS) + BLOG_DECL(BLOG_NOTIFY_EVT_MAX) +} blog_notify_evt_type_t; + +/* Traffic type */ +typedef enum { + BLOG_DECL(BlogTraffic_IPV4_UCAST) + BLOG_DECL(BlogTraffic_IPV6_UCAST) + BLOG_DECL(BlogTraffic_IPV4_MCAST) + BLOG_DECL(BlogTraffic_IPV6_MCAST) + BLOG_DECL(BlogTraffic_Layer2_Flow) + BLOG_DECL(BlogTraffic_MAX) +} BlogTraffic_t; + +typedef union { + uint32_t word; + struct { + BE_DECL( + uint32_t incarn : 3; /* Allocation instance identification */ + uint32_t self : 29; /* Index into static allocation table */ + ) + LE_DECL( + uint32_t self : 29; /* Index into static allocation table */ + uint32_t incarn : 3; /* Allocation instance identification */ + ) + }; +} BlogKeyFc_t; + +typedef union { + uint32_t word; + struct { + BE_DECL( + + uint32_t resvd : 23; + uint32_t client_type: 1; + uint32_t client : 8; + ) + LE_DECL( + uint32_t client : 8; + uint32_t client_type: 1; + uint32_t resvd : 23; + ) + }; +} BlogKeyMc_t; + +#define BLOG_FDB_KEY_INVALID BLOG_KEY_NONE +#define BLOG_KEY_FC_INVALID BLOG_KEY_NONE +#define BLOG_KEY_FC_TUNNEL_IPV4 0xFFFFFFFE +#define BLOG_KEY_FC_TUNNEL_IPV6 0xFFFFFFFF + +#define BLOG_KEY_INVALID BLOG_KEY_NONE +#define BLOG_KEY_MCAST_INVALID BLOG_KEY_INVALID + +/* mcast client type: TX device only, TX device & MAC address */ +#define BLOG_MCAST_CLIENT_TYPE_TXDEV 0 +#define BLOG_MCAST_CLIENT_TYPE_TXDEV_MACDA 1 + +typedef struct { + BE_DECL( + BlogKeyFc_t fc; + BlogKeyMc_t mc; + ) + LE_DECL( + BlogKeyMc_t mc; + BlogKeyFc_t fc; + ) +} BlogActivateKey_t; + +typedef enum +{ + BLOG_DECL(BLOG_L2_KEYMAP_MACSA) + BLOG_DECL(BLOG_L2_KEYMAP_MACDA) + BLOG_DECL(BLOG_L2_KEYMAP_ETHTYPE) + BLOG_DECL(BLOG_L2_KEYMAP_VLAN0) + BLOG_DECL(BLOG_L2_KEYMAP_VLAN1) + BLOG_DECL(BLOG_L2_KEYMAP_TOS) + BLOG_DECL(BLOG_L2_KEYMAP_TCPACK) +} blog_l2_keymap_field_t; + +typedef enum +{ + BLOG_DECL(BLOG_L3_KEYMAP_IPV4SA) + BLOG_DECL(BLOG_L3_KEYMAP_IPV4DA) + BLOG_DECL(BLOG_L3_KEYMAP_IPV6SA) + BLOG_DECL(BLOG_L3_KEYMAP_IPV6DA) + BLOG_DECL(BLOG_L3_KEYMAP_PROTO) + BLOG_DECL(BLOG_L3_KEYMAP_SPORT) + BLOG_DECL(BLOG_L3_KEYMAP_DPORT) + BLOG_DECL(BLOG_L3_KEYMAP_TOS) + BLOG_DECL(BLOG_L3_KEYMAP_TCPACK) +} blog_l3_keymap_field_t; + + +#define BLOG_SET_L2KEYMAP(b, v0, v1, t) \ + b->l2_keymap = (1<<BLOG_L2_KEYMAP_MACSA \ + | 1<<BLOG_L2_KEYMAP_MACDA \ + | 1<<BLOG_L2_KEYMAP_ETHTYPE \ + | v0<<BLOG_L2_KEYMAP_VLAN0 \ + | v1<<BLOG_L2_KEYMAP_VLAN1 \ + | t<<BLOG_L2_KEYMAP_TOS) + +#define BLOG_SET_IPV4_PT_L3KEYMAP(b) \ + b->l3_keymap = (1<<BLOG_L3_KEYMAP_IPV4SA \ + | 1<<BLOG_L3_KEYMAP_IPV4DA \ + | 1<<BLOG_L3_KEYMAP_PROTO \ + | 1<<BLOG_L3_KEYMAP_TOS) + +#define BLOG_SET_IPV4_L3KEYMAP(b) \ + b->l3_keymap = (1<<BLOG_L3_KEYMAP_IPV4SA \ + | 1<<BLOG_L3_KEYMAP_IPV4DA \ + | 1<<BLOG_L3_KEYMAP_PROTO \ + | 1<<BLOG_L3_KEYMAP_SPORT \ + | 1<<BLOG_L3_KEYMAP_DPORT \ + | 1<<BLOG_L3_KEYMAP_TOS) + +#define BLOG_SET_IPV6_PT_L3KEYMAP(b) \ + b->l3_keymap = (1<<BLOG_L3_KEYMAP_IPV6SA \ + | 1<<BLOG_L3_KEYMAP_IPV6DA \ + | 1<<BLOG_L3_KEYMAP_PROTO \ + | 1<<BLOG_L3_KEYMAP_TOS) + +#define BLOG_SET_IPV6_L3KEYMAP(b) \ + b->l3_keymap = (1<<BLOG_L3_KEYMAP_IPV6SA \ + | 1<<BLOG_L3_KEYMAP_IPV6DA \ + | 1<<BLOG_L3_KEYMAP_PROTO \ + | 1<<BLOG_L3_KEYMAP_SPORT \ + | 1<<BLOG_L3_KEYMAP_DPORT \ + | 1<<BLOG_L3_KEYMAP_TOS) + + +/* Is the megaflow valid ? */ +#define IS_BLOG_MEGA(b) (((b)->mega_p != (void *)NULL)) + +/* Is the map tuple valid ? */ +#define IS_BLOG_MAP(b) ( MAPT(b) && ((b)->map_p != (void *)NULL) ) + +/* Before the flow is learnt, use CT macros */ +#define IS_BLOG_CT_PLD(b) ( (b)->ct_p[BLOG_CT_PLD] != (void *)NULL ) +#define IS_BLOG_CT_DEL(b) ( (b)->ct_p[BLOG_CT_DEL] != (void *)NULL ) +#define IS_BLOG_CT(b) ( IS_BLOG_CT_PLD((b)) || IS_BLOG_CT_DEL((b)) ) +#define IS_BLOG_NOT_CT(b) ( !IS_BLOG_CT_PLD((b)) && !IS_BLOG_CT_DEL((b)) ) + +#define IS_BLOG_CT4_PLD(b) \ + ( IS_BLOG_CT_PLD((b)) && \ + ((b)->ct_ver[BLOG_CT_PLD] == BLOG_PARAM2_IPV4)) + +#define IS_BLOG_CT4_DEL(b) \ + ( IS_BLOG_CT_DEL((b)) && \ + ((b)->ct_ver[BLOG_CT_DEL] == BLOG_PARAM2_IPV4)) + +#define IS_BLOG_CT6_PLD(b) \ + ( IS_BLOG_CT_PLD((b)) && \ + ((b)->ct_ver[BLOG_CT_PLD] == BLOG_PARAM2_IPV6)) + +#define IS_BLOG_CT6_DEL(b) \ + ( IS_BLOG_CT_DEL((b)) && \ + ((b)->ct_ver[BLOG_CT_DEL] == BLOG_PARAM2_IPV6)) + +#define IS_BLOG_CT4(b) ( IS_BLOG_CT4_PLD(b) || IS_BLOG_CT4_DEL(b) ) +#define IS_BLOG_CT6(b) ( IS_BLOG_CT6_PLD(b) || IS_BLOG_CT6_DEL(b) ) + + +#define BLOG_NPE_PLD 0U +#define BLOG_NPE_DEL 1U +#define BLOG_NPE_MAP 2U +#define BLOG_NPE_MEGA 3U +#define BLOG_NPE_MAX 4U + +#define BLOG_FDB_NPE_SRCFDB 0U +#define BLOG_FDB_NPE_DSTFDB 1U +#define BLOG_FDB_NPE_MAX 2U + +/* Is the map tuple valid ? */ +#define IS_BLOG_NPE_MAP(b) ( MAPT(b) && ((b)->npe_p[BLOG_NPE_MAP] != (void *)NULL) ) +#define IS_BLOG_NPE_MEGA(b) ( ((b)->npe_p[BLOG_NPE_MEGA] != (void *)NULL) ) + +/* After the flow is learnt, use NPE macros instead of CT macros */ +#define IS_BLOG_NPE_PLD(b) ( (b)->npe_p[BLOG_NPE_PLD] != (void *)NULL ) +#define IS_BLOG_NPE_DEL(b) ( (b)->npe_p[BLOG_NPE_DEL] != (void *)NULL ) +#define IS_BLOG_NPE_CT(b) ( IS_BLOG_NPE_PLD((b)) || IS_BLOG_NPE_DEL((b)) ) +#define IS_BLOG_NOT_NPE_CT(b) ( !IS_BLOG_NPE_PLD((b)) && !IS_BLOG_NPE_DEL((b)) ) + +#define IS_BLOG_NPE4_PLD(b) \ + ( IS_BLOG_NPE_PLD((b)) && \ + ((b)->ct_ver[BLOG_NPE_PLD] == BLOG_PARAM2_IPV4)) + +#define IS_BLOG_NPE4_DEL(b) \ + ( IS_BLOG_NPE_DEL((b)) && \ + ((b)->ct_ver[BLOG_NPE_DEL] == BLOG_PARAM2_IPV4)) + +#define IS_BLOG_NPE6_PLD(b) \ + ( IS_BLOG_NPE_PLD((b)) && \ + ((b)->ct_ver[BLOG_NPE_PLD] == BLOG_PARAM2_IPV6)) + +#define IS_BLOG_NPE6_DEL(b) \ + ( IS_BLOG_NPE_DEL((b)) && \ + ((b)->ct_ver[BLOG_NPE_DEL] == BLOG_PARAM2_IPV6)) + +#define IS_BLOG_NPE4(b) ( IS_BLOG_NPE4_PLD(b) || IS_BLOG_NPE4_DEL(b) ) +#define IS_BLOG_NPE6(b) ( IS_BLOG_NPE6_PLD(b) || IS_BLOG_NPE6_DEL(b) ) + +#define BLOG_NPE_NULL ((blog_npe_t*)NULL) + +/* + *------------------------------------------------------------------------------ + * Flow Cache network proxiy entity (npe) Entry: + *------------------------------------------------------------------------------ + */ +struct blog_npe { + struct dll_t node; /* npe Entity list */ + BlogKeyFc_t key; /* linking Linux nwe and npe entity */ + struct blog_npe *chain_p; /* npe Entity Hash list node */ + uint32_t hashix; /* npe Entity hash index */ + + int type; /* npe Entity type */ + void *nwe_p; + Dll_t flow_list[BLOG_PARAM1_DIR_MAX]; /* flow lists */ + uint32_t flow_count[BLOG_PARAM1_DIR_MAX]; /* # of flows */ +} ____cacheline_aligned; +typedef struct blog_npe blog_npe_t; + + +/* + * ============================================================================= + * CAUTION: OS and network stack may be built without CONFIG_BLOG defined. + * ============================================================================= + */ + +#if defined(CONFIG_BLOG) + +/* + *------------------------------------------------------------------------------ + * + * Section: Blog Conditional Compiles CC_BLOG_SUPPORT_... + * + * These conditional compiles are not controlled by a system wide build process. + * E.g. CONFIG_BLOG_MCAST is a system wide build configuration + * CC_BLOG_SUPPORT_MCAST is a blog defined build configuration + * + * Do not use any CONFIG_ or CC_BLOG_SUPPORT_ in Blog_t structure definitions. + * + *------------------------------------------------------------------------------ + */ + +/* LAB ONLY: Design development, uncomment to enable */ +/* #define CC_BLOG_SUPPORT_COLOR */ +/* #define CC_BLOG_SUPPORT_DEBUG */ + + + + +/* To enable user filtering, see blog_filter(), invoked in blog_finit() */ +/* #define CC_BLOG_SUPPORT_USER_FILTER */ + + + +/* + * ----------------------------------------------------------------------------- + * Section: Definition of a Blog_t + * ----------------------------------------------------------------------------- + */ + +#define HDR_BMAP_IPV4 1 +#define HDR_BMAP_IPV6 2 +#define HDR_BMAP_L2 3 + +/* GREoESP flag indicates whether it is GRE over ESP, or ESP over GRE */ +#define BLOG_ESPoGRE 0 +#define BLOG_GREoESP 1 + +#define BLOG_GREoESP_44 0 +#define BLOG_GREoESP_64 1 +#define BLOG_GREoESP_46 2 +#define BLOG_GREoESP_66 3 + +#define BLOG_ESPoGRE_44 0 +#define BLOG_ESPoGRE_64 1 +#define BLOG_ESPoGRE_46 2 +#define BLOG_ESPoGRE_66 3 + +typedef struct { + + uint8_t channel; /* e.g. port number, txchannel, ... */ + + union { + struct { + uint8_t phyHdrLen : 4; + uint8_t phyHdrType : 4; + }; + uint8_t phyHdr; + }; + + uint16_t unused; + + union { + struct { + BE_DECL( + uint32_t unused : 3; + uint32_t VXLAN : 1; + uint32_t LLC_SNAP : 1; + uint32_t PLD_DST_OPTS: 1; /* Payload IPv6 Ext Hdr Dest Options */ + uint32_t DEL_DST_OPTS: 1; /* Delivery IPv6 Ext Hdr Dest Options */ + uint32_t PASS_THRU : 1; + + uint32_t NPT6 : 1; + uint32_t GREoESP : 1; + uint32_t GREoESP_type: 2; + uint32_t HDR0_L2 : 1; + uint32_t HDR0_IPv6 : 1; + uint32_t HDR0_IPv4 : 1; + uint32_t PLD_L2 : 1; + + uint32_t DEL_L2 : 1; + uint32_t DEL_IPv6 : 1; + uint32_t DEL_IPv4 : 1; + uint32_t ESP : 1; + uint32_t GRE : 1; + uint32_t L2TP : 1; + uint32_t PPTP : 1; + uint32_t PLD_IPv6 : 1; + + uint32_t PLD_IPv4 : 1; + uint32_t PPP_1661 : 1; + uint32_t PPPoE_2516 : 1; + uint32_t VLAN_8021Q : 1; + uint32_t ETH_802x : 1; + uint32_t BCM_SWC : 1; + uint32_t BCM_XPHY : 1; /* e.g. BCM_XTM */ + uint32_t GRE_ETH : 1; /* Ethernet over GRE */ + ) + LE_DECL( + uint32_t GRE_ETH : 1; /* Ethernet over GRE */ + uint32_t BCM_XPHY : 1; /* e.g. BCM_XTM */ + uint32_t BCM_SWC : 1; + uint32_t ETH_802x : 1; + uint32_t VLAN_8021Q : 1; + uint32_t PPPoE_2516 : 1; + uint32_t PPP_1661 : 1; + uint32_t PLD_IPv4 : 1; + + uint32_t PLD_IPv6 : 1; + uint32_t PPTP : 1; + uint32_t L2TP : 1; + uint32_t GRE : 1; + uint32_t ESP : 1; + uint32_t DEL_IPv4 : 1; + uint32_t DEL_IPv6 : 1; + uint32_t DEL_L2 : 1; + + uint32_t PLD_L2 : 1; + uint32_t HDR0_IPv4 : 1; + uint32_t HDR0_IPv6 : 1; + uint32_t HDR0_L2 : 1; + uint32_t GREoESP_type: 2; + uint32_t GREoESP : 1; + uint32_t NPT6 : 1; + + uint32_t PASS_THRU : 1; + uint32_t DEL_DST_OPTS: 1; /* Delivery IPv6 Ext Hdr Dest Options */ + uint32_t PLD_DST_OPTS: 1; /* Payload IPv6 Ext Hdr Dest Options */ + uint32_t LLC_SNAP : 1; + uint32_t VXLAN : 1; + uint32_t unused : 3; + ) + } bmap;/* as per order of BlogEncap_t enums declaration */ + uint32_t hdrs; + }; +} BlogInfo_t; + +/* + *------------------------------------------------------------------------------ + * Buffer to log IP Tuple. + * Packed: 1 16byte cacheline. + *------------------------------------------------------------------------------ + */ +struct blogTuple_t { + uint32_t saddr; /* IP header saddr */ + uint32_t daddr; /* IP header daddr */ + + union { + struct { + uint16_t source; /* L4 source port */ + uint16_t dest; /* L4 dest port */ + } port; + struct { + uint16_t unused; + uint16_t gre_callid; + }; + uint32_t ports; + uint32_t esp_spi; + }; + + uint8_t ttl; /* IP header ttl */ + uint8_t tos; /* IP header tos */ + uint16_t check; /* checksum: rx tuple=l3, tx tuple=l4 */ + +}; +typedef struct blogTuple_t BlogTuple_t; + +#define NEXTHDR_IPV4 IPPROTO_IPIP +#define GRE_MAX_HDR_LEN (sizeof(struct ipv6hdr) + sizeof(BLOG_HDRSZ_MAX) + BLOG_GRE_HDR_LEN) + +#define HDRS_IPinIP ((1<<GREoESP) | (3<<GREoESP_type) | (1<<GRE) | (1<<ESP) | \ + (1<<PLD_IPv4) | (1<<PLD_IPv6) | (1<<PLD_L2) | \ + (1<<HDR0_IPv4) | (1<<HDR0_IPv6) | (1<<HDR0_L2) | \ + (1<<DEL_IPv4) | (1<<DEL_IPv6) | (1<<DEL_L2) | (1<<VXLAN)) +#define HDRS_IP4in4 ((1<<PLD_IPv4) | (1<<DEL_IPv4)) +#define HDRS_IP6in4 ((1<<PLD_IPv6) | (1<<DEL_IPv4)) +#define HDRS_IP4in6 ((1<<PLD_IPv4) | (1<<DEL_IPv6)) +#define HDRS_IP6in6 ((1<<PLD_IPv6) | (1<<DEL_IPv6)) +#define HDRS_GIP4 ((1<<PLD_IPv4) | (1<<GRE)) +#define HDRS_GIP6 ((1<<PLD_IPv6) | (1<<GRE)) +#define HDRS_GL2 ((1<<PLD_L2) | (1<<GRE)) +#define HDRS_EIP4 ((1<<PLD_IPv4) | (1<<ESP)) +#define HDRS_IP2in4 ((1<<PLD_L2) | (1<<DEL_IPv4)) +#define HDRS_IP2in6 ((1<<PLD_L2) | (1<<DEL_IPv6)) +#define HDRS_EIP4in6 ((1<<PLD_IPv4) | (1<<DEL_IPv6) | (1<<ESP)) + +#define RX_IP4in6(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_IP4in6) +#define RX_IP6in4(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_IP6in4) +#define TX_IP4in6(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_IP4in6) +#define TX_IP6in4(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_IP6in4) + +#define RX_IPV4(b) ((b)->rx.info.bmap.PLD_IPv4) +#define TX_IPV4(b) ((b)->tx.info.bmap.PLD_IPv4) +#define RX_IPV6(b) ((b)->rx.info.bmap.PLD_IPv6) +#define TX_IPV6(b) ((b)->tx.info.bmap.PLD_IPv6) +#define RX_IPV4_DEL(b) ((b)->rx.info.bmap.DEL_IPv4) +#define TX_IPV4_DEL(b) ((b)->tx.info.bmap.DEL_IPv4) +#define RX_IPV6_DEL(b) ((b)->rx.info.bmap.DEL_IPv6) +#define TX_IPV6_DEL(b) ((b)->tx.info.bmap.DEL_IPv6) +#define PT(b) ((b)->tx.info.bmap.PASS_THRU) + +#define RX_GRE(b) ((b)->rx.info.bmap.GRE) +#define TX_GRE(b) ((b)->tx.info.bmap.GRE) +#define RX_ESP(b) ((b)->rx.info.bmap.ESP) +#define TX_ESP(b) ((b)->tx.info.bmap.ESP) +#define RX_GRE_ETH(b) ((b)->rx.info.bmap.GRE_ETH) +#define TX_GRE_ETH(b) ((b)->tx.info.bmap.GRE_ETH) +#define TX_VXLAN(b) ((b)->tx.info.bmap.VXLAN) +#define RX_VXLAN(b) ((b)->rx.info.bmap.VXLAN) +#define VXLAN(b) (TX_VXLAN(b) || RX_VXLAN(b)) + +#define RX_IPV4ONLY(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==(1 << PLD_IPv4)) +#define TX_IPV4ONLY(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==(1 << PLD_IPv4)) +#define RX_IPV6ONLY(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==(1 << PLD_IPv6)) +#define TX_IPV6ONLY(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==(1 << PLD_IPv6)) +#define RX_L2ONLY(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==(1 << PLD_L2)) +#define TX_L2ONLY(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==(1 << PLD_L2)) + +#define CHK_RX_GIPV4(b) (((b)->rx.info.hdrs & ((1 << DEL_IPv4) | (1 << PLD_IPv4))) && RX_GRE(b)) +#define CHK_RX_GIPV6(b) (((b)->rx.info.hdrs & ((1 << DEL_IPv6) | (1 << PLD_IPv6))) && RX_GRE(b)) + + +#define RX_IPV4_OUTER(b) (RX_IPV4ONLY(b) || RX_IPV4_DEL(b)) +#define TX_IPV4_OUTER(b) (TX_IPV4ONLY(b) || TX_IPV4_DEL(b)) +#define PT4(b) (RX_IPV4ONLY(b) && TX_IPV4ONLY(b) && PT(b)) + +#define RX_IPV6_OUTER(b) (RX_IPV6ONLY(b) || RX_IPV6_DEL(b)) +#define TX_IPV6_OUTER(b) (TX_IPV6ONLY(b) || TX_IPV6_DEL(b)) +#define PT6(b) (RX_IPV6ONLY(b) && TX_IPV6ONLY(b) && PT(b)) + +#define HDRS_IPV4 ((1 << PLD_IPv4) | (1 << DEL_IPv4)) +#define HDRS_IPV6 ((1 << PLD_IPv6) | (1 << DEL_IPv6)) + +#define MAPT_UP(b) (RX_IPV4ONLY(b) && TX_IPV6ONLY(b)) +#define MAPT_DN(b) (RX_IPV6ONLY(b) && TX_IPV4ONLY(b)) +#define MAPT(b) (MAPT_DN(b) || MAPT_UP(b)) + +#define T4in6UP(b) (RX_IPV4ONLY(b) && TX_IP4in6(b)) +#define T4in6DN(b) (RX_IP4in6(b) && TX_IPV4ONLY(b)) + +#define T6in4UP(b) (RX_IPV6ONLY(b) && TX_IP6in4(b)) +#define T6in4DN(b) (RX_IP6in4(b) && TX_IPV6ONLY(b)) + +#define CHK4in6(b) (T4in6UP(b) || T4in6DN(b)) +#define CHK6in4(b) (T6in4UP(b) || T6in4DN(b)) +#define CHK4to4(b) (RX_IPV4ONLY(b) && TX_IPV4ONLY(b)) +#define CHK6to6(b) (RX_IPV6ONLY(b) && TX_IPV6ONLY(b)) + +/* RX/TX is ESPv4 */ +#define RX_E4(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==((1 << PLD_IPv4)|(1 << ESP))) +#define TX_E4(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==((1 << PLD_IPv4)|(1 << ESP))) + +/* RX/TX ESPv4 over DSLite tunnel WAN side */ +#define RX_E4in6(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_EIP4in6) +#define TX_E4in6(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_EIP4in6) + +/* ESPv4 pass-thru over DSLite tunnel */ +#define EoT4in6UP(b) (RX_E4(b) && TX_E4in6(b)) +#define EoT4in6DN(b) (RX_E4in6(b) && TX_E4(b)) + +#define HDRS_GIP4in4 ((1<<GRE) | HDRS_IP4in4) +#define HDRS_GIP6in4 ((1<<GRE) | HDRS_IP6in4) +#define HDRS_GIP2in4 ((1<<GRE) | HDRS_IP2in4) + +#define HDRS_GIP4in6 ((1<<GRE) | HDRS_IP4in6) +#define HDRS_GIP6in6 ((1<<GRE) | HDRS_IP6in6) +#define HDRS_GIP2in6 ((1<<GRE) | HDRS_IP2in6) + +#define RX_GIPV4ONLY(b) (((b)->rx.info.hdrs & HDRS_IPinIP)== HDRS_GIP4) +#define TX_GIPV4ONLY(b) (((b)->tx.info.hdrs & HDRS_IPinIP)== HDRS_GIP4) +#define RX_GIPV6ONLY(b) (((b)->rx.info.hdrs & HDRS_IPinIP)== HDRS_GIP6) +#define TX_GIPV6ONLY(b) (((b)->tx.info.hdrs & HDRS_IPinIP)== HDRS_GIP6) +#define RX_GL2ONLY(b) (((b)->rx.info.hdrs & HDRS_IPinIP)== HDRS_GL2) +#define TX_GL2ONLY(b) (((b)->tx.info.hdrs & HDRS_IPinIP)== HDRS_GL2) + +#define RX_GIP4in4(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_GIP4in4) +#define TX_GIP4in4(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_GIP4in4) +#define RX_GIP6in4(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_GIP6in4) +#define TX_GIP6in4(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_GIP6in4) +#define RX_GIP2in4(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_GIP2in4) +#define TX_GIP2in4(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_GIP2in4) +#define RX_GIP46in4(b) (RX_GIP4in4(b) || RX_GIP6in4(b)) +#define TX_GIP46in4(b) (TX_GIP4in4(b) || TX_GIP6in4(b)) + +#define RX_GIP4in6(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_GIP4in6) +#define TX_GIP4in6(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_GIP4in6) +#define RX_GIP6in6(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_GIP6in6) +#define TX_GIP6in6(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_GIP6in6) +#define RX_GIP2in6(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_GIP2in6) +#define TX_GIP2in6(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_GIP2in6) +#define RX_GIP46in6(b) (RX_GIP4in6(b) || RX_GIP6in6(b)) +#define TX_GIP46in6(b) (TX_GIP4in6(b) || TX_GIP6in6(b)) + +#define TG4in4UP(b) (RX_IPV4ONLY(b) && TX_GIP4in4(b)) +#define TG4in4DN(b) (RX_GIP4in4(b) && TX_IPV4ONLY(b)) +#define TG6in4UP(b) (RX_IPV6ONLY(b) && TX_GIP6in4(b)) +#define TG6in4DN(b) (RX_GIP6in4(b) && TX_IPV6ONLY(b)) +#define TG2in4UP(b) (RX_L2ONLY(b) && TX_GIP2in4(b)) +#define TG2in4DN(b) (RX_GIP2in4(b) && TX_L2ONLY(b)) + +#define TGL3_4in4UP(b) (RX_IPV4ONLY(b) && !TX_GRE_ETH(b) && TX_GIP4in4(b)) +#define TGL3_4in4DN(b) (!RX_GRE_ETH(b) && RX_GIP4in4(b) && TX_IPV4ONLY(b)) +#define TGL2_4in4UP(b) (RX_IPV4ONLY(b) && TX_GRE_ETH(b) && TX_GIP4in4(b)) +#define TGL2_4in4DN(b) (RX_GRE_ETH(b) && RX_GIP4in4(b) && TX_IPV4ONLY(b)) +#define TGL2_2in4UP(b) (RX_L2ONLY(b) && TX_GRE_ETH(b) && TX_GIP2in4(b)) +#define TGL2_2in4DN(b) (RX_GRE_ETH(b) && RX_GIP2in4(b) && TX_L2ONLY(b)) + +#define TG4in6UP(b) (RX_IPV4ONLY(b) && TX_GIP4in6(b)) +#define TG4in6DN(b) (RX_GIP4in6(b) && TX_IPV4ONLY(b)) +#define TG6in6UP(b) (RX_IPV6ONLY(b) && TX_GIP6in6(b)) +#define TG6in6DN(b) (RX_GIP6in6(b) && TX_IPV6ONLY(b)) +#define TG2in6UP(b) (RX_L2ONLY(b) && TX_GIP2in6(b)) +#define TG2in6DN(b) (RX_GIP2in6(b) && TX_L2ONLY(b)) + +#define TG24in4UP(b) (TG4in4UP(b) || TG2in4UP(b)) +#define TG24in4DN(b) (TG4in4DN(b) || TG2in4DN(b)) + +#define TG24in6UP(b) (TG4in6UP(b) || TG2in6UP(b)) +#define TG24in6DN(b) (TG4in6DN(b) || TG2in6DN(b)) + +#define CHKG4in4(b) (TG4in4UP(b) || TG4in4DN(b)) +#define CHKG6in4(b) (TG6in4UP(b) || TG6in4DN(b)) +#define CHKG2in4(b) (TG2in4UP(b) || TG2in4DN(b)) +#define CHKG46in4UP(b) (TG4in4UP(b) || TG6in4UP(b)) +#define CHKG46in4DN(b) (TG4in4DN(b) || TG6in4DN(b)) +#define CHKG46in4(b) (CHKG4in4(b) || CHKG6in4(b)) +#define CHKG246in4UP(b) (TG4in4UP(b) || TG6in4UP(b) || TG2in4UP(b)) +#define CHKG246in4DN(b) (TG4in4DN(b) || TG6in4DN(b) || TG2in4DN(b)) +#define CHKG246in4(b) (CHKG4in4(b) || CHKG6in4(b) || CHKG2in4(b)) + +#define CHKG4in6(b) (TG4in6UP(b) || TG4in6DN(b)) +#define CHKG6in6(b) (TG6in6UP(b) || TG6in6DN(b)) +#define CHKG2in6(b) (TG2in6UP(b) || TG2in6DN(b)) +#define CHKG46in6UP(b) (TG4in6UP(b) || TG6in6UP(b)) +#define CHKG46in6DN(b) (TG4in6DN(b) || TG6in6DN(b)) +#define CHKG46in6(b) (CHKG4in6(b) || CHKG6in6(b)) +#define CHKG246in6UP(b) (TG4in6UP(b) || TG6in6UP(b) || TG2in6UP(b)) +#define CHKG246in6DN(b) (TG4in6DN(b) || TG6in6DN(b) || TG2in6DN(b)) +#define CHKG246in6(b) (CHKG4in6(b) || CHKG6in6(b) || CHKG2in6(b)) + +#define PTG4(b) (RX_GIPV4ONLY(b) && TX_GIPV4ONLY(b) && PT(b)) +#define PTG6(b) (RX_GIPV6ONLY(b) && TX_GIPV6ONLY(b) && PT(b)) +#define TOTG4(b) (!PT(b) && ((RX_GIP4in4(b) && TX_GIP4in4(b)) || \ + (RX_GIP6in4(b) && TX_GIP6in4(b)))) +#define TOTG6(b) (!PT(b) && ((RX_GIP4in6(b) && TX_GIP4in6(b)) || \ + (RX_GIP6in6(b) && TX_GIP6in6(b)))) + +#define L2ACCEL_PTG(b) (RX_GL2ONLY(b) && TX_GL2ONLY(b)) + +#define HDRS_EIP4in4 ((1<<ESP) | HDRS_IP4in4) +#define HDRS_EIP6in4 ((1<<ESP) | HDRS_IP6in4) + +#define RX_EIPV4ONLY(b) (((b)->rx.info.hdrs & HDRS_IPinIP)== HDRS_EIP4) +#define TX_EIPV4ONLY(b) (((b)->tx.info.hdrs & HDRS_IPinIP)== HDRS_EIP4) + +#define RX_EIP4in4(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_EIP4in4) +#define TX_EIP4in4(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_EIP4in4) +#define RX_EIP6in4(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_EIP6in4) +#define TX_EIP6in4(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_EIP6in4) + +#define TE4in4UP(b) (RX_IPV4ONLY(b) && TX_EIP4in4(b)) +#define TE4in4DN(b) (RX_EIP4in4(b) && TX_IPV4ONLY(b)) +#define TE6in4UP(b) (RX_IPV6ONLY(b) && TX_EIP6in4(b)) +#define TE6in4DN(b) (RX_EIP6in4(b) && TX_IPV6ONLY(b)) + +#define CHKE4in4(b) (TE4in4UP(b) || TE4in4DN(b)) +#define CHKE6in4(b) (TE6in4UP(b) || TE6in4DN(b)) +#define CHKE46in4(b) (CHKE4in4(b) || CHKE6in4(b)) + +#define PTE4(b) (RX_EIPV4ONLY(b) && TX_EIPV4ONLY(b)) + +#define HDRS_404 (1<<DEL_IPv4|1<<PLD_IPv4) +#define HDRS_464 (1<<DEL_IPv4|1<<HDR0_IPv6|1<<PLD_IPv4) +#define HDRS_606 (1<<DEL_IPv6|1<<PLD_IPv6) +#define HDRS_646 (1<<DEL_IPv6|1<<HDR0_IPv4|1<<PLD_IPv4) + +#define RX_404(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_404) +#define RX_464(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_464) +#define RX_606(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_606) +#define RX_646(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_646) + + +#define HDRS_444 (1<<DEL_IPv4|1<<HDR0_IPv4|1<<PLD_IPv4) +#define HDRS_644 (1<<DEL_IPv4|1<<HDR0_IPv4|1<<PLD_IPv6) +#define HDRS_244 (1<<DEL_IPv4|1<<HDR0_IPv4|1<<PLD_L2) + + +/* GRE over ESP */ +#define HDRS_4oG4oE4 (BLOG_GREoESP_44<<GREoESP_type|1<<GREoESP|1<<ESP|1<<GRE|HDRS_444) +#define HDRS_6oG4oE4 (BLOG_GREoESP_44<<GREoESP_type|1<<GREoESP|1<<ESP|1<<GRE|HDRS_644) +#define HDRS_2oG4oE4 (BLOG_GREoESP_44<<GREoESP_type|1<<GREoESP|1<<ESP|1<<GRE|HDRS_244) +/* HDRS_GE2 excludes IP Hdrs */ +#define HDRS_GE2 (BLOG_GREoESP_44<<GREoESP_type|1<<GREoESP|1<<ESP|1<<GRE|1<<PLD_L2) + +#define RX_4oG4oE4(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_4oG4oE4) +#define TX_4oG4oE4(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_4oG4oE4) +#define RX_6oG4oE4(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_6oG4oE4) +#define TX_6oG4oE4(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_6oG4oE4) +#define RX_2oG4oE4(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_2oG4oE4) +#define TX_2oG4oE4(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_2oG4oE4) +#define RX_GoEo2(b) (((b)->rx.info.hdrs & HDRS_IPinIP)==HDRS_GE2) +#define TX_GoEo2(b) (((b)->tx.info.hdrs & HDRS_IPinIP)==HDRS_GE2) + +#define T4oG4oE4UP(b) (RX_IPV4ONLY(b) && TX_4oG4oE4(b)) +#define T4oG4oE4DN(b) (RX_4oG4oE4(b) && TX_IPV4ONLY(b)) +#define T6oG4oE4UP(b) (RX_IPV6ONLY(b) && TX_6oG4oE4(b)) +#define T6oG4oE4DN(b) (RX_6oG4oE4(b) && TX_IPV6ONLY(b)) +#define T2oG4oE4UP(b) (RX_L2ONLY(b) && (TX_2oG4oE4(b) || TX_GoEo2(b))) +#define T2oG4oE4DN(b) ((RX_2oG4oE4(b) || RX_GoEo2(b)) && TX_L2ONLY(b)) + +#define CHK4oG4oE4UP(b) (T4oG4oE4UP(b)) +#define CHK4oG4oE4DN(b) (T4oG4oE4DN(b)) +#define CHK4oG4oE4(b) (CHK4oG4oE4UP(b) || CHK4oG4oE4DN(b)) + +#define CHK6oG4oE4UP(b) (T6oG4oE4UP(b)) +#define CHK6oG4oE4DN(b) (T6oG4oE4DN(b)) +#define CHK6oG4oE4(b) (CHK6oG4oE4UP(b) || CHK6oG4oE4DN(b)) + +#define CHK46oG4oE4DN(b) (CHK4oG4oE4DN(b) || CHK6oG4oE4DN(b)) +#define CHK46oG4oE4UP(b) (CHK4oG4oE4UP(b) || CHK6oG4oE4UP(b)) +#define CHK46oG4oE4(b) (CHK4oG4oE4(b) || CHK6oG4oE4(b)) + +#define CHK2oG4oE4UP(b) (T2oG4oE4UP(b)) +#define CHK2oG4oE4DN(b) (T2oG4oE4DN(b)) +#define CHK2oG4oE4(b) (CHK2oG4oE4UP(b) || CHK2oG4oE4DN(b)) + + +#define CHK246oG4oE4UP(b) (CHK4oG4oE4UP(b) || CHK6oG4oE4UP(b) || CHK2oG4oE4UP(b)) +#define CHK246oG4oE4DN(b) (CHK4oG4oE4DN(b) || CHK6oG4oE4DN(b) || CHK2oG4oE4DN(b)) +#define CHK246oG4oE4(b) (CHK4oG4oE4(b) || CHK6oG4oE4(b) || CHK2oG4oE4(b)) + + +#define RX_PPTP(b) ((b)->rx.info.bmap.PPTP) +#define TX_PPTP(b) ((b)->tx.info.bmap.PPTP) + +#define RX_L2TP(b) ((b)->rx.info.bmap.L2TP) +#define TX_L2TP(b) ((b)->tx.info.bmap.L2TP) + +#define CHK_RX_L2TP(b) (((b)->rx.info.hdrs & ((1 << DEL_IPv4) | (1 << PLD_IPv4))) && RX_L2TP(b)) +#define CHK_TX_L2TP(b) (((b)->rx.info.hdrs & ((1 << DEL_IPv4) | (1 << PLD_IPv4))) && TX_L2TP(b)) + +#define RX_PPPOE(b) ((b)->rx.info.bmap.PPPoE_2516) +#define TX_PPPOE(b) ((b)->tx.info.bmap.PPPoE_2516) +#define PT_PPPOE(b) (RX_PPPOE(b) && TX_PPPOE(b)) + +#define PKT_IPV6_GET_TOS_WORD(word) \ + ((ntohl(word) & 0x0FF00000) >> 20) + +#define PKT_IPV6_SET_TOS_WORD(word, tos) \ + (word = htonl((ntohl(word) & 0xF00FFFFF) | ((tos << 20) & 0x0FF00000))) + +/* BLOG_LOCK Definitions */ +extern spinlock_t blog_lock_g; +#define BLOG_LOCK_BH() spin_lock_bh( &blog_lock_g ) +#define BLOG_UNLOCK_BH() spin_unlock_bh( &blog_lock_g ) + +typedef struct ip6_addr { + union { + uint8_t p8[16]; + uint16_t p16[8]; + uint32_t p32[4]; + }; +} ip6_addr_t; + +/* + *------------------------------------------------------------------------------ + * Buffer to log IPv6 Tuple. + * Packed: 3 16byte cachelines + *------------------------------------------------------------------------------ + */ +struct blogTupleV6_t { + union { + uint32_t word0; + }; + + union { + uint32_t word1; + struct { + uint16_t length; + uint8_t next_hdr; + uint8_t rx_hop_limit; + }; + }; + + ip6_addr_t saddr; + ip6_addr_t daddr; + + union { + struct { + uint16_t source; /* L4 source port */ + uint16_t dest; /* L4 dest port */ + } port; + uint32_t ports; + }; + + union { + struct { + uint8_t exthdrs:6; /* Bit field of IPv6 extension headers */ + uint8_t fragflag:1; /* 6in4 Upstream IPv4 fragmentation flag */ + uint8_t tunnel:1; /* Indication of IPv6 tunnel */ + uint8_t tx_hop_limit; + uint16_t ipid; /* 6in4 Upstream IPv4 identification */ + }; + uint32_t word2; + }; + + union { + struct { + uint8_t nextHdr; uint8_t hdrLen; uint16_t data16; + uint32_t data32; + }; + uint64_t ip6_ExtHdr; + }; + + ip6_addr_t addr_npt6; +} ____cacheline_aligned; +typedef struct blogTupleV6_t BlogTupleV6_t; + +typedef union blogGreFlags { + uint16_t u16; + struct { + BE_DECL( + uint16_t csumIe : 1; + uint16_t rtgIe : 1; + uint16_t keyIe : 1; + uint16_t seqIe : 1; + uint16_t srcRtIe: 1; + uint16_t recurIe: 3; + uint16_t ackIe : 1; + + uint16_t flags : 4; + uint16_t ver : 3; + ) + LE_DECL( + uint16_t ver : 3; + uint16_t flags : 4; + + uint16_t ackIe : 1; + uint16_t recurIe: 3; + uint16_t srcRtIe: 1; + uint16_t seqIe : 1; + uint16_t keyIe : 1; + uint16_t rtgIe : 1; + uint16_t csumIe : 1; + ) + }; +} BlogGreFlags_t; + +struct blogGre_t { + uint8_t l2hdr[ BLOG_HDRSZ_MAX ]; /* Data of all L2 headers */ + BlogGreFlags_t gre_flags; + union { + uint16_t u16; + struct { + BE_DECL( + uint16_t reserved : 10; + uint16_t fragflag : 1; + uint16_t hlen : 5; + ) + LE_DECL( + uint16_t hlen : 5; + uint16_t fragflag : 1; + uint16_t reserved : 10; + ) + }; + }; + uint16_t ipid; + uint16_t l2_hlen; + + union { //pptp + struct { + uint16_t keyLen; + uint16_t keyId; + }; + uint32_t key; + }; + uint32_t seqNum; + uint32_t ackNum; + uint16_t pppInfo; + uint16_t pppProto; +}; + +typedef struct blogGre_t BlogGre_t; + +typedef union blogL2tpFlags { + uint16_t u16; + struct { + BE_DECL( + uint16_t type : 1; + uint16_t lenBit : 3; + uint16_t seqBit : 2; + uint16_t offsetBit : 1; + uint16_t priority : 1; + uint16_t reserved : 4; + uint16_t version : 4; + ) + LE_DECL( + uint16_t version : 4; + uint16_t reserved : 4; + uint16_t priority : 1; + int16_t offsetBit : 1; + uint16_t seqBit : 2; + uint16_t lenBit : 3; + uint16_t type : 1; + ) + }; +} BlogL2tpFlags_t; + +struct blogL2tp_t { + BlogL2tpFlags_t l2tp_flags; + uint16_t length; + uint16_t tunnelId; + uint16_t sessionId; + uint16_t seqNum; + uint16_t expSeqNum; + uint16_t offsetSize; + uint16_t offsetPad; + union { + uint16_t u16; + struct { + BE_DECL( + uint16_t reserved : 10; + uint16_t fragflag : 1; + uint16_t hlen : 5; + ) + LE_DECL( + uint16_t hlen : 5; + uint16_t fragflag : 1; + uint16_t reserved : 10; + ) + }; + }; + uint16_t ipid; + uint16_t unused; + uint16_t udpLen; + uint16_t udpCheck; + uint16_t pppInfo; + uint16_t pppProto; + +}; +typedef struct blogL2tp_t BlogL2tp_t; + +#define BLOG_PPP_ADDR_CTL 0xFF03 +#define BLOG_L2TP_PPP_LEN 4 /* used when PPP address and control is 0xFF03 */ +#define BLOG_L2TP_PPP_LEN2 2 /* used when PPP address and control is NOT 0xFF03 */ +#define BLOG_L2TP_PORT 1701 + +#define BLOG_PPTP_PPP_LEN 4 +#define BLOG_PPTP_NOAC_PPPINFO 0X2145 /* pptp packet without ppp address control field 0xff03 */ + +#define BLOG_ESP_SPI_LEN 4 +#define BLOG_ESP_SEQNUM_LEN 4 +#define BLOG_ESP_PADLEN_LEN 1 +#define BLOG_ESP_NEXT_PROTO_LEN 1 + +#define BLOG_ESP_ICV_LEN_64 8 +#define BLOG_ESP_ICV_LEN_96 12 +#define BLOG_ESP_ICV_LEN_128 16 +#define BLOG_ESP_ICV_LEN_192 24 +#define BLOG_ESP_ICV_LEN_224 28 +#define BLOG_ESP_ICV_LEN_256 32 +#define BLOG_ESP_ICV_LEN_384 48 +#define BLOG_ESP_ICV_LEN_512 64 + +struct blogEsp_t { + uint32_t u32; + union { + uint16_t u16; + struct { + BE_DECL( + uint16_t icvsize : 7; + uint16_t pmtudiscen : 1; + uint16_t ipv6 : 1; + uint16_t ipv4 : 1; + uint16_t fragflag : 1; + uint16_t ivsize : 5; + ) + LE_DECL( + uint16_t ivsize : 5; + uint16_t fragflag : 1; + uint16_t ipv4 : 1; + uint16_t ipv6 : 1; + uint16_t pmtudiscen : 1; + uint16_t icvsize : 7; + ) + }; + }; + uint16_t ipid; + void *dst_p; + void *secPath_p; +}; +typedef struct blogEsp_t BlogEsp_t; + + +struct blogVxlan_t { + uint32_t vni; + union { + uint16_t u16; + struct { + BE_DECL( + uint16_t reserved : 6; + uint16_t ipv6 : 1; + uint16_t ipv4 : 1; + uint16_t length : 8; + ) + LE_DECL( + uint16_t length : 8; + uint16_t ipv4 : 1; + uint16_t ipv6 : 1; + uint16_t reserved : 6; + ) + }; + }; + uint8_t l2len; + uint8_t unused; /*for alignment */ + uint8_t tunnel_data[BLOG_VXLAN_TUNNEL_MAX_LEN]; +}; +typedef struct blogVxlan_t BlogVxlan_t; + + +/* + *------------------------------------------------------------------------------ + * Buffer to log Layer 2 and IP Tuple headers. + * Packed: 4 16byte cachelines + *------------------------------------------------------------------------------ + */ +struct blogHeader_t { + + BlogTuple_t tuple; /* L3+L4 IP Tuple log */ + + union { + BlogInfo_t info; + union { + struct { + uint32_t word1; /* channel, count, rfc2684, bmap */ + uint32_t word; /* channel, count, rfc2684, bmap */ + }; + uint32_t pktlen; /* stats info */ + }; + }; + + struct { + uint8_t vlan_8021ad :1; /* 8021AD stacked */ + uint8_t wan_qdisc :1; /* device type */ + uint8_t multicast :1; /* multicast flag */ + uint8_t fkbInSkb :1; /* fkb from skb */ + uint8_t count :4; /* # of L2 encapsulations */ + }; + uint8_t length; /* L2 header total length */ + uint8_t /*BlogEncap_t*/ encap[ BLOG_ENCAP_MAX ];/* All L2 header types */ + + uint8_t l2hdr[ BLOG_HDRSZ_MAX ]; /* Data of all L2 headers */ + struct { + uint8_t unused; + uint8_t len_offset; + union { + uint16_t frame_len; + int16_t len_delta; + }; + } llc_snap; +} ____cacheline_aligned; + +typedef struct blogHeader_t BlogHeader_t; /* L2 and L3+4 tuple */ + +/* Coarse hash key: L1, L3, L4 hash */ +union blogHash_t { + uint32_t match; + struct { + union { + struct { + uint8_t tcp_pure_ack : 1; + uint8_t llc_snap : 1; + uint8_t unused : 6; + }; + uint8_t ext_match; + }; + uint8_t protocol; /* IP protocol */ + + union { + uint16_t u16; + struct { + uint8_t channel; + union { + struct { + uint8_t phyLen : 4; + uint8_t phyType : 4; + }; + uint8_t phy; + }; + }; + } l1_tuple; + }; +}; + +typedef union blogHash_t BlogHash_t; + + +/* flow priority - used for packet buffer reseravtion */ +typedef enum { + BLOG_DECL(flow_prio_normal) + BLOG_DECL(flow_prio_high) + BLOG_DECL(flow_prio_exclusive) +} BlogFlowPrio_t; + + +/* TBD : Rearrange following bit positions for optimization. */ +union blogWfd_t { + uint32_t u32; + struct { + BE_DECL( + uint32_t is_rx_hw_acc_en : 1;/* =1 if WLAN Receive is capable of HW Acceleration */ + uint32_t is_tx_hw_acc_en : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */ + uint32_t is_wfd : 1;/* is_wfd=1 */ + uint32_t is_wmf_enabled : 1; /* =0 unused */ + uint32_t chain_idx : 16;/* Tx chain index */ + uint32_t is_chain : 1;/* is_chain=1 */ + uint32_t reserved1 : 3;/* unused */ + uint32_t wfd_prio : 1;/* 0=high, 1=low */ + uint32_t wfd_idx : 2;/* WFD idx */ + uint32_t reserved0 : 1;/* unused */ + uint32_t priority : 4;/* Tx Priority */ + ) + LE_DECL( + uint32_t priority : 4;/* Tx Priority */ + uint32_t reserved0 : 1;/* unused */ + uint32_t wfd_idx : 2;/* WFD idx */ + uint32_t wfd_prio : 1;/* 0=high, 1=low */ + uint32_t reserved1 : 3;/* unused */ + uint32_t is_chain : 1;/* is_chain=1 */ + uint32_t chain_idx : 16;/* Tx chain index */ + uint32_t is_wmf_enabled : 1; /* =0 unused */ + uint32_t is_wfd : 1;/* is_wfd=1 */ + uint32_t is_tx_hw_acc_en : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */ + uint32_t is_rx_hw_acc_en : 1;/* =1 if WLAN Receive is capable of HW Acceleration */ + ) + } nic_ucast; + + struct { + BE_DECL( + uint32_t is_rx_hw_acc_en : 1;/* =1 if WLAN Receive is capable of HW Acceleration */ + uint32_t is_tx_hw_acc_en : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */ + uint32_t is_wfd : 1;/* is_wfd=1 */ + uint32_t is_wmf_enabled : 1; /* =0 unused */ + uint32_t flowring_idx :16;/* Tx flowring index */ + uint32_t is_chain : 1;/* is_chain=0 */ + uint32_t wfd_prio : 1;/* 0=high, 1=low */ + uint32_t ssid : 4;/* SSID for WLAN */ + uint32_t reserved1 : 1;/* unused */ + uint32_t wfd_idx : 2;/* WFD idx */ + uint32_t priority : 3;/* Tx Priority */ + ) + LE_DECL( + uint32_t priority : 3;/* Tx Priority */ + uint32_t wfd_idx : 2;/* WFD idx */ + uint32_t reserved1 : 1;/* unused */ + uint32_t ssid : 4;/* SSID for WLAN */ + uint32_t wfd_prio : 1;/* 0=high, 1=low */ + uint32_t is_chain : 1;/* is_chain=0 */ + uint32_t flowring_idx :16;/* Tx flowring index */ + uint32_t is_wmf_enabled : 1; /* =0 unused */ + uint32_t is_wfd : 1;/* is_wfd=1 */ + uint32_t is_tx_hw_acc_en : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */ + uint32_t is_rx_hw_acc_en : 1;/* =1 if WLAN Receive is capable of HW Acceleration */ + ) + } dhd_ucast; + + struct { + BE_DECL( + uint32_t is_rx_hw_acc_en : 1;/* =1 if WLAN Receive is capable of HW Acceleration */ + uint32_t is_tx_hw_acc_en : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */ + uint32_t is_wfd : 1;/* is_wfd=1 */ + uint32_t is_wmf_enabled : 1; /* =1 if wmf enabled */ + uint32_t sta_id : 16;/* uniq wifi identifier, NIC max 2048*/ + uint32_t is_chain : 1;/* is_chain=0 */ + uint32_t wfd_idx : 2;/* WFD idx */ + uint32_t wfd_prio : 1;/* 0=high, 1=low */ + uint32_t reserved1 : 2;/* unused */ + uint32_t ssid : 4;/* SSID */ + uint32_t reserved0 : 2;/* unused */ + ) + LE_DECL( + uint32_t reserved0 : 2; /* unused */ + uint32_t ssid : 4;/* SSID */ + uint32_t reserved1 : 2;/* unused */ + uint32_t wfd_prio : 1;/* 0=high, 1=low */ + uint32_t wfd_idx : 2;/* WFD idx */ + uint32_t is_chain : 1;/* is_chain=0 */ + uint32_t sta_id : 16;/* uniq wifi sta identifier, NIC max 2048*/ + uint32_t is_wmf_enabled : 1; /* =1 if wmf enabled */ + uint32_t is_wfd : 1;/* is_wfd=1 */ + uint32_t is_tx_hw_acc_en : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */ + uint32_t is_rx_hw_acc_en : 1;/* =1 if WLAN Receive is capable of HW Acceleration */ + ) + } mcast; +}; +typedef union blogWfd_t BlogWfd_t; + +struct blogRnr_t { + BE_DECL( + uint32_t is_rx_hw_acc_en : 1;/* =1 if WLAN Receive is capable of HW Acceleration */ + uint32_t is_tx_hw_acc_en : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */ + uint32_t is_wfd : 1;/* rnr (is_wfd=0) */ + uint32_t is_wmf_enabled : 1; /* =1 if wmf enabled */ + uint32_t flowring_idx :16;/* Tx flowring index */ + uint32_t radio_idx : 2;/* Radio index */ + uint32_t llcsnap_flag : 1;/* llcsnap_flag */ + uint32_t priority : 3;/* Tx Priority */ + uint32_t ssid : 4;/* SSID */ + uint32_t flow_prio : 2;/* flow priority (normal,high, exclusive) - used for packet buffer reservation */ + ) + LE_DECL( + uint32_t flow_prio : 2;/* flow priority (normal,high, exclusive) - used for packet buffer reservation */ + uint32_t ssid : 4;/* SSID */ + uint32_t priority : 3;/* Tx Priority */ + uint32_t llcsnap_flag : 1;/* llcsnap_flag */ + uint32_t radio_idx : 2;/* Radio index */ + uint32_t flowring_idx :16;/* Tx flowring index */ + uint32_t is_wmf_enabled : 1; /* =1 if wmf enabled */ + uint32_t is_wfd : 1;/* rnr (is_wfd=0) */ + uint32_t is_tx_hw_acc_en : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */ + uint32_t is_rx_hw_acc_en : 1;/* =1 if WLAN Receive is capable of HW Acceleration */ + ) +}; + +typedef struct blogRnr_t BlogRnr_t; + +#define MAX_NUM_VLAN_TAG 2 + +/* Blog ingress priority derived from IQOS */ +typedef enum { + BLOG_DECL(BLOG_IQ_PRIO_LOW) + BLOG_DECL(BLOG_IQ_PRIO_HIGH) +} BlogIqPrio_t; + +#define BLOG_GET_MASK(b) (1ULL<<(b)) + +#define BLOG_BITS_PER_WORD 32 +#if (BLOG_BITS_PER_WORD != 32) +#error "BLOG_BITS_PER_WORD should be 32" +#endif + +#define BLOG_MCAST_CLIENT_BITMAP_MAX_WORDS ((CONFIG_BCM_MAX_MCAST_CLIENTS_PER_GROUP>>5)+1) +#define BLOG_MCAST_CLIENT_BITMAP_SIZE (BLOG_MCAST_CLIENT_BITMAP_MAX_WORDS * BLOG_BITS_PER_WORD) +#define BLOG_MCAST_MASTER_CLIENT_ID 0 +#define BLOG_MCAST_FIRST_CLIENT_ID 1 + +/* DSL RDP: first few mcast client ids reserved for non-WLAN clients (Enet, XTM (DPU case, etc.) */ +#define BLOG_MCAST_ENET_CLIENT_RESERVED_IDS 7 +#define BLOG_MCAST_LAST_CLIENT_ID (CONFIG_BCM_MAX_MCAST_CLIENTS_PER_GROUP) + +#define BLOG_MCAST_DEV_REALLOC_COUNT 16 + +typedef struct { + uint16_t unused; + uint16_t max_dev; /* max number of allocated devices in the table */ + uint16_t num_dev; /* number of used devices in the table */ + uint16_t last_dev_idx; /* index of last used device in the table */ + uint8_t *ref_tbl_p; /* table of ref count (of device) pointers */ + int8_t *delta_tbl_p; /* table of dev delta pointers */ + void **dev_tbl_pp; /* table of dev pointers */ +} mcast_dev_info_t; + +/* + *------------------------------------------------------------------------------ + * Buffer log structure. + * ARM 32: 704 bytes + * ARM 64: 896 bytes + * MIPS : 704 bytes + * Marked the cacheline boundaries in the below structure. + * Be cautious when adding new members to this structure. + *------------------------------------------------------------------------------ + */ +struct blog_t { + + union { + void * void_p; + struct blog_t * blog_p; /* Free list of Blog_t */ + struct sk_buff * skb_p; /* Associated sk_buff */ + }; + BlogHash_t key; /* Coarse hash search key */ + uint32_t hash; /* hash */ + union { + uint32_t wl; + struct { + BE_DECL( + uint32_t is_rx_hw_acc_en : 1;/* =1 if WLAN Receive is capable of HW Acceleration */ + uint32_t is_tx_hw_acc_en : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */ + uint32_t reserved : 30; + ) + LE_DECL( + uint32_t reserved : 30; + uint32_t is_tx_hw_acc_en : 1;/* =1 if WLAN Transmit is capable of HW Acceleartion */ + uint32_t is_rx_hw_acc_en : 1;/* =1 if WLAN Receive is capable of HW Acceleration */ + ) + } wl_hw_support; + BlogWfd_t wfd; + BlogRnr_t rnr; + }; + uint32_t fc_context; + void * mc_fdb; /* physical rx network device */ + + void *map_p; + /* --- [ARM32]32 byte cacheline boundary --- */ + BlogEthAddr_t src_mac; /* Flow src MAC */ + BlogEthAddr_t dst_mac; /* Flow dst MAC */ + /* --- [ARM64]64 byte cacheline boundary --- */ + + void * fdb[2]; /* fdb_src and fdb_dst */ + uint32_t ifidx[2]; /* fdb src and fdb dst bridge ifidx */ + int8_t delta[MAX_VIRT_DEV]; /* octet delta info */ + int8_t tx_dev_delta; /* octet delta of TX dev */ + uint8_t l2_dirty_offset; + uint8_t vtag_num: 4; + uint8_t vtag_tx_num: 4; + uint16_t eth_type; + /* --- [ARM32]32 byte cacheline boundary --- */ + + union { + uint32_t flags; + struct { + BE_DECL( + uint32_t fwd_and_trap:1; + uint32_t mcast_fwd_exception: 1; + uint32_t is_routed: 1; + uint32_t fc_hybrid: 1; /* hybrid flow accelarate in HW and SW */ + uint32_t l2_mode: 1; + uint32_t is_ssm: 1; + uint32_t unused2: 1; + + uint32_t l2_pppoe: 1; /* L2 packet is PPPoE */ + uint32_t l2_ipv6: 1; /* L2 packet is IPv6 */ + uint32_t l2_ipv4: 1; /* L2 packet is IPv4 */ + uint32_t is_mapt_us: 1; /* MAP-T Upstream flow */ + uint32_t is_df: 1; /* IPv4 DF flag set */ + uint32_t ptm_us_bond: 1; /* PTM US Bonding Mode */ + uint32_t lag_port: 2; /* LAG port when trunking is done by internal switch/runner */ + + uint32_t tos_mode_us: 1; /* ToS mode for US: fixed, inherit */ + uint32_t tos_mode_ds: 1; /* ToS mode for DS: fixed, inherit */ + uint32_t has_pppoe: 1; + uint32_t ack_done: 1; /* TCP ACK prio decision made */ + uint32_t ack_cnt: 4; /* back to back TCP ACKs for prio */ + + uint32_t nf_dir_pld: 1; + uint32_t nf_dir_del: 1; + uint32_t nf_ct_skip_ref_dec: 1; /* when set don't decrement ct refcnt */ + uint32_t pop_pppoa: 1; + uint32_t insert_eth: 1; + uint32_t iq_prio: 1; + uint32_t mc_sync: 1; + uint32_t rtp_seq_chk: 1; /* RTP sequence check enable */ + uint32_t unused1: 1; + ) + LE_DECL( + uint32_t unused1: 1; + uint32_t rtp_seq_chk: 1; /* RTP sequence check enable */ + uint32_t mc_sync: 1; + uint32_t iq_prio: 1; + uint32_t insert_eth: 1; + uint32_t pop_pppoa: 1; + uint32_t nf_ct_skip_ref_dec: 1; /* when set don't decrement ct refcnt */ + uint32_t nf_dir_del: 1; + uint32_t nf_dir_pld: 1; + + uint32_t ack_cnt: 4; /* back to back TCP ACKs for prio */ + uint32_t ack_done: 1; /* TCP ACK prio decision made */ + uint32_t has_pppoe: 1; + uint32_t tos_mode_ds: 1; /* ToS mode for DS: fixed, inherit */ + uint32_t tos_mode_us: 1; /* ToS mode for US: fixed, inherit */ + + uint32_t lag_port: 2; /* LAG port when trunking is done by internal switch/runner */ + uint32_t ptm_us_bond: 1; /* PTM US Bonding Mode */ + uint32_t is_df: 1; /* IPv4 DF flag set */ + uint32_t is_mapt_us: 1; /* MAP-T Upstream flow */ + uint32_t l2_ipv4: 1; /* L2 packet is IPv4 */ + uint32_t l2_ipv6: 1; /* L2 packet is IPv6 */ + uint32_t l2_pppoe: 1; /* L2 packet is PPPoE */ + + uint32_t unused2: 1; + uint32_t is_ssm: 1; + uint32_t l2_mode: 1; + uint32_t fc_hybrid: 1; /* hybrid flow accelarate in HW and SW */ + uint32_t is_routed: 1; + uint32_t mcast_fwd_exception: 1; + uint32_t fwd_and_trap:1; + ) + }; + }; + union { + uint32_t flags2; + struct { + BE_DECL( + uint32_t unused: 31; + uint32_t mcast_dev_added: 1; + ) + LE_DECL( + uint32_t mcast_dev_added: 1; + uint32_t unused: 31; + ) + }; + }; + union { + /* only the lower 32 bit in mark is used in 64 bit system + * but we declare it as unsigned long for the ease of blog + * to handle it in different architecture, since it part + * of union with a dst_entry pointer */ + unsigned long mark; /* NF mark value on tx */ + void *dst_entry; /* skb dst_entry for local_in */ + }; + + union { + uint32_t priority; /* Tx priority */ + uint32_t flowid; /* used only for local in */ + }; + + void * blogRule_p; /* List of Blog Rules */ + + union { + struct { + uint32_t dosAttack : 16; + uint32_t lenPrior : 1; + uint32_t vlanPrior : 1; + uint32_t dscpMangl : 1; + uint32_t tosMangl : 1; + uint32_t preMod : 1; + uint32_t postMod : 1; + uint32_t dscp2pbit : 1; + uint32_t dscp2q : 1; + uint32_t reserved : 8; + }; + uint32_t feature; /* Feature set for per-packet modification */ + }; + union { + struct { + uint8_t vlanout_offset; /* Outer VLAN header offset */ + uint8_t vlanin_offset; /* Inner VLAN header offset */ + uint8_t vpass_tx_offset; /* Passthru VLAN headers tx offset */ + uint8_t vpass_len; /* Passthru VLAN headers length */ + uint8_t pppoe_offset; /* PPPoE header offset */ + uint8_t ip_offset; /* IPv4 header offset */ + uint8_t ip6_offset; /* IPv6 header offset */ + uint8_t l4_offset; /* Layer 4 header offset */ + uint8_t isWan; /* Receiving by WAN interface */ + uint8_t reserved8_3[3]; + }; + uint32_t offsets[3]; + }; + /* --- [ARM32][ARM64] cacheline boundary --- */ + int (*preHook)(Blog_t *blog_p, void *nbuff_p); /* Pre-modify hook */ + int (*postHook)(Blog_t *blog_p, void *nbuff_p); /* Post-modify hook */ + /* vtag[] stored in network order to improve fcache performance */ + uint32_t vtag[MAX_NUM_VLAN_TAG]; + /* pointers to the devices which the flow goes thru */ + void * virt_dev_p[MAX_VIRT_DEV]; + /* --- [ARM32][ARM64]cacheline boundary --- */ + void *fdb_npe_p[BLOG_FDB_NPE_MAX]; /* FDB NPEs */ + void *npe_p[BLOG_NPE_MAX]; /* non-FDB NPEs*/ + /* --- [ARM32][ARM64]cacheline boundary --- */ + + //BlogTupleV6_t and BlogHeader_t is cacheline_aligned structure, be + //be cautious when adding new variables around these memeber as it + //will create unwanted holes in the structure. + BlogTupleV6_t tupleV6; /* L3+L4 IP Tuple log */ + BlogTupleV6_t del_tupleV6; /* Del GRE L3+L4 IPV6 Tuple log */ + + BlogHeader_t tx; /* Transmit path headers */ + BlogHeader_t rx; /* Receive path headers */ + /* --- [ARM32][ARM64]cacheline boundary --- */ + + void *rx_dev_p; /* RX physical network device */ + void *tx_dev_p; /* TX physical network device */ + + unsigned long dev_xmit; + int (*dev_xmit_blog)(void * nbuff_p,const Blog_t * const blog_p); /* Xmit with blog */ + + /* Flow connection/session tracker */ + void *ct_p[BLOG_CT_MAX]; + uint32_t ct_ver[BLOG_CT_VER_MAX]; + /* --- [ARM32]32 byte cacheline boundary --- */ + void *rx_tunl_p; + /* --- [ARM64]64 byte cacheline boundary --- */ + void *tx_tunl_p; + BlogActivateKey_t activate_key; + uint8_t tx_l4_offset; /*offset to inner most L4 header*/ + uint8_t tx_l3_offset; /*offset to inner most L3 header*/ + uint16_t mcast_port_map; + uint16_t mcast_excl_udp_port; + + uint16_t minMtu; + uint8_t dpi_queue; + uint8_t tuple_offset; /* offset of flow tuple header */ + uint8_t hw_pathstat_idx; /* HWACC Pathstat index */ + uint8_t host_mac_hashix; + uint8_t spdtst; + + /* To make cache alignment inserting dummy_ptr */ + uint8_t dummy_data2; + union { + uint16_t wlinfo; + uint16_t wlsta_id; + }; + + /* --- [ARM32]32 byte cacheline boundary --- */ + BlogTuple_t *grerx_tuple_p; /* gre proto RX Tuple pointer */ + BlogTuple_t *gretx_tuple_p; /* gre proto TX Tuple pointer */ + union { + struct { + BlogGre_t grerx; + /* --- [ARM32][ARM64]cacheline boundary --- */ + BlogGre_t gretx; + }; + struct { + BlogL2tp_t l2tptx; + }; + BlogVxlan_t vxlan; + }; + /* --- [ARM32]32 byte cacheline boundary (was 24 bytes ago)--- */ + BlogTuple_t *esprx_tuple_p; /* ESP proto RX Tuple pointer */ + BlogTuple_t *esptx_tuple_p; /* ESP proto TX Tuple pointer */ + /* --- [ARM32]32 byte cacheline boundary --- */ + struct { + BlogEsp_t esprx; + /* --- [ARM64]64 byte cacheline boundary --- */ + BlogEsp_t esptx; + }; + /* --- [ARM32]32 byte cacheline boundary --- */ + BlogTuple_t delrx_tuple; /* Del proto RX L3+L4 IP Tuple log */ + BlogTuple_t deltx_tuple; /* Del proto TX L3+L4 IP Tuple log */ + /* --- [ARM32][ARM64]cacheline boundary --- */ + BlogTuple_t rx_tuple[1]; /* RX L3+L4 IP Tuple log */ + BlogTuple_t tx_tuple[1]; /* TX L3+L4 IP Tuple log */ + void *mega_p; + + uint32_t l2_keymap; + uint32_t l3_keymap; + uint8_t mcast_client_type; + uint8_t mcast_client_id; + int16_t mcast_bitmap_idx; /* index into mcast bitmap pool */ + mcast_dev_info_t *mcast_dev_info_p; /* master mcast dev info */ +} ____cacheline_aligned; + +/* + * ----------------------------------------------------------------------------- + * Engineering constants: Pre-allocated pool size 400 blogs Ucast+Mcast + * + * Extensions done in #blogs carved from a 2x4K page (external fragmentation) + * Blog size = 240, 8192/240 = 34 extension 32bytes internal fragmentation + * + * Number of extensions engineered to permit approximately max # of flows + * (assuming one blog per flow). + * ----------------------------------------------------------------------------- + */ +#define CC_BLOG_SUPPORT_EXTEND /* Conditional compile */ +#define BLOG_POOL_SIZE_ENGG 400 /* Pre-allocated pool size */ +/* Number of Blog_t per extension */ +#define BLOG_EXTEND_SIZE_ENGG (8192/sizeof(Blog_t)) + +/* There is one additional mcast flow entry for each mcast group because of a master flow */ +#define BLOG_CONFIG_MAX_MCAST_FLOWS (CONFIG_BCM_MAX_MCAST_GROUPS + CONFIG_BCM_MAX_MCAST_CLIENTS) +#define BLOG_CONFIG_MAX_FLOWS (CONFIG_BCM_MAX_UCAST_FLOWS + BLOG_CONFIG_MAX_MCAST_FLOWS) + +/* Maximum extensions allowed */ +#define BLOG_EXTEND_MAX_ENGG ((BLOG_CONFIG_MAX_FLOWS/BLOG_EXTEND_SIZE_ENGG) + 1) + + + +extern const char * strBlogAction[]; +extern const char * strBlogEncap[]; +extern const char * strRfc2684[]; +extern const uint8_t rfc2684HdrLength[]; +extern const uint8_t rfc2684HdrData[][16]; + + +#else +struct blog_t {void * blogRule_p;}; +#define BLOG_LOCK_BH() +#define BLOG_UNLOCK_BH() +#endif /* defined(CONFIG_BLOG) */ + +/* + * ----------------------------------------------------------------------------- + * Blog functional interface + * ----------------------------------------------------------------------------- + */ + + +/* + * ----------------------------------------------------------------------------- + * Section 1. Extension of a packet context with a logging context + * ----------------------------------------------------------------------------- + */ + +#if defined(CONFIG_BLOG) +#define blog_ptr(skb_p) skb_p->blog_p +#else +#define blog_ptr(skb_p) BLOG_NULL +#endif + +/* Allocate or deallocate a Blog_t */ +Blog_t * blog_get(void); +void blog_put(Blog_t * blog_p); + +/* Allocate a Blog_t and associate with sk_buff or fkbuff */ +extern Blog_t * blog_skb(struct sk_buff * skb_p); +extern Blog_t * blog_fkb(struct fkbuff * fkb_p); + +/* Clear association of Blog_t with sk_buff */ +extern Blog_t * blog_snull(struct sk_buff * skb_p); +extern Blog_t * blog_fnull(struct fkbuff * fkb_p); + +/* increment refcount of ct's associated with blog */ +extern void blog_ct_get(Blog_t * blog_p); +/* decrement refcount of ct's associated with blog */ +extern void blog_ct_put(Blog_t * blog_p); + +/* increment refcount for devices in virt_dev_p array */ +extern void blog_dev_hold(const Blog_t * blog_p); +/* decrement refcount for devices in virt_dev_p array */ +extern void blog_dev_put(Blog_t * blog_p); + +/* Clear association of Blog_t with sk_buff and free Blog_t object */ +extern void blog_free( struct sk_buff * skb_p, blog_skip_reason_t reason ); + +/* Disable further logging. Dis-associate with skb and free Blog object */ +extern void blog_skip(struct sk_buff * skb_p, blog_skip_reason_t reason); + +/* Transfer association of a Blog_t object between two sk_buffs. */ +extern void blog_xfer(struct sk_buff * skb_p, const struct sk_buff * prev_p); + +/* Duplicate a Blog_t object for another skb. */ +extern void blog_clone(struct sk_buff * skb_p, const struct blog_t * prev_p); + +/* Copy a Blog_t object another blog object. */ +extern void blog_copy(struct blog_t * new_p, const struct blog_t * prev_p); + +/* get the Ingress QoS Prio from the blog */ +extern int blog_iq(const struct sk_buff * skb_p); + +/* get the flow cache status */ +extern int blog_fc_enabled(void); + +/* get the GRE tunnel accelerated status */ +extern int blog_gre_tunnel_accelerated(void); + +#define BLOG_PTM_US_BONDING_DISABLED 0 +#define BLOG_PTM_US_BONDING_ENABLED 1 + +extern void blog_ptm_us_bonding( struct sk_buff *skb_p, int mode ); + +typedef int (*blog_dhd_flow_update_t)(void*, char*, char*, int); +extern blog_dhd_flow_update_t blog_dhd_flow_update_fn; +extern int blog_is_config_netdev_mac(void *dev_p, unsigned long incl_vmacs); +extern int blog_preemptible_task(void); + +#if defined(CONFIG_BLOG) +/* gets an NWE from blog based on the NPE type */ +static inline void *_blog_get_nwe(Blog_t *blog_p, uint32_t npe_type) +{ + blog_npe_t *npe_p = (blog_npe_t *)blog_p->npe_p[npe_type]; + return (npe_p ? npe_p->nwe_p : (void *) NULL); +} +#endif + +/* + *------------------------------------------------------------------------------ + * Section 2. Associating native OS or 3rd-party network constructs + *------------------------------------------------------------------------------ + */ + +extern void blog_link(BlogNetEntity_t entity_type, Blog_t * blog_p, + void * net_p, uint32_t param1, uint32_t param2); + +/* + *------------------------------------------------------------------------------ + * Section 3. Network construct and Blog client co-existence call backs + *------------------------------------------------------------------------------ + */ + +extern unsigned long blog_request(BlogRequest_t event, void * net_p, + unsigned long param1, unsigned long param2); + +extern int blog_query(BlogQuery_t query, void * net_p, + uint32_t param1, uint32_t param2, unsigned long param3); + +/* + * blog_notify(): + * blog_notify() is a synchrounous notification from an entity to blog/flow_cache + * and will return once the notification/event has been completed. + * This API should be called only when it is known that the event processing time + * is going to be short (process or interrupt context). + * + * Interrupt Context: It is NOT recommended to call blog_notify() from an + * interrupt context (like softirq/timer) because it will block all other + * processes/threads/softirq from running until the notification processing + * has been completed. Instead use blog_notify_async() from an interrupt + * context. + */ +extern void blog_notify(BlogNotify_t event, void *net_p, + unsigned long param1, unsigned long param2); + +/* + * fc_evt task will invoke this callback function asynchronously once the + * event processing has been completed. It is upto each entity to decide what + * it wants to do within this callback but it should not hold the fc_evt task + * for too long. + */ +typedef void (*blog_notify_async_cb_fn_t)(void *notify_cb_data_p); + +/* + * blog_notify_async(): + * It is same as blog_notify() except two new parameters (notify_cb_fn and + * notify_cb_data_p) have been added, and it is asynchronous call. notify_cb_fn + * function will be called with notify_cb_data_p parameter on completion of + * the event processing. If an caller does not want to wait for the completion + * of the event it can pass NULL values for notify_cb_fn and notify_cb_data_p. + * + * blog_notify_async() can be called from process or interrupt context, + * it will not block/sleep in this call. If blocking is needed it should be + * done outside this API. + * + * CAUTION: Responsibility of the calling entity: + * - Serialization and/or locking, reference count of entry + * - the entry (e.g. flowring, FDB, etc.) for which flows are being flused + * is NOT freed or reallocated before the callback function is invoked. + * + * return: Caller MUST check the return value. + * 1 : caller's notify callback function will be called + * 0 : caller's notify callback function will NOT be called. + * Situations where fc_evt task is not running. + */ +extern int blog_notify_async(BlogNotify_t event, void *net_p, + unsigned long param1, unsigned long param2, + blog_notify_async_cb_fn_t notify_cb_fn, void *notify_cb_data_p); + +/* + *------------------------------------------------------------------------------ + * blog_notify_async_wait + * Calls blog_notify_async() and then waits for completion of event. No callback + * function needed from the caller, this function uses its own callback function. + * Note : If called from NOT preempt-safe context, this function will change + * blog_notify_async() to blog_notify(), which means the event is + * processed synchronously. + * Caller should not call blog_lock()/blog_unlock() as this fucntion + * internally calls blog_lock before calling blog_notify/_async() APIs, + * and blog_unlock after calling. + *------------------------------------------------------------------------------ + */ +extern void blog_notify_async_wait(BlogNotify_t event, void *net_p, + unsigned long param1, unsigned long param2); + +/* blog notify event enqueue function type */ +typedef int (*blog_notify_evt_enqueue_hook_t)(blog_notify_evt_type_t evt_type, + void *net_p, unsigned long param1, unsigned long param2, + blog_notify_async_cb_fn_t notify_cb_fn, void *notify_cb_data_p); + +void blog_bind_notify_evt_enqueue( + blog_notify_evt_enqueue_hook_t blog_notify_evt_enqueue_fn ); +/* + *------------------------------------------------------------------------------ + * Section 4. Network end-point binding of Blog client + * + * If rx hook is defined, + * blog_sinit(): initialize a fkb from skb, and pass to hook + * if packet is consumed, skb is released. + * if packet is blogged, the blog is associated with skb. + * blog_finit(): pass to hook + * if packet is to be blogged, the blog is associated with fkb. + * + * If tx hook is defined, invoke tx hook, dis-associate and free Blog_t + *------------------------------------------------------------------------------ + */ +extern BlogAction_t _blog_sinit( struct sk_buff * skb_p, void * dev_p, + uint32_t encap, uint32_t channel, + uint32_t phyHdr, BlogFcArgs_t *fc_args ); + +static inline BlogAction_t blog_sinit( struct sk_buff * skb_p, void * dev_p, + uint32_t encap, uint32_t channel, + uint32_t phyHdr ) +{ + /*TODO move this allocation to drivers calling this function */ + BlogFcArgs_t fc_args; + memset(&fc_args, 0, sizeof(BlogFcArgs_t)); + return _blog_sinit(skb_p, dev_p, encap, channel, phyHdr, &fc_args); +} + +static inline BlogAction_t blog_sinit_args( struct sk_buff * skb_p, void * dev_p, + uint32_t encap, uint32_t channel, + uint32_t phyHdr, BlogFcArgs_t *fc_args ) +{ + return _blog_sinit(skb_p, dev_p, encap, channel, phyHdr, fc_args); +} + +extern BlogAction_t _blog_finit( struct fkbuff * fkb_p, void * dev_p, + uint32_t encap, uint32_t channel, + uint32_t phyHdr, BlogFcArgs_t *fc_args ); + +static inline BlogAction_t blog_finit( struct fkbuff * fkb_p, void * dev_p, + uint32_t encap, uint32_t channel, + uint32_t phyHdr ) +{ + /*TODO move this allocation to drivers calling this function */ + BlogFcArgs_t fc_args; + memset(&fc_args, 0, sizeof(BlogFcArgs_t)); + return _blog_finit(fkb_p, dev_p, encap, channel, phyHdr, &fc_args); +} + +static inline BlogAction_t blog_finit_args( struct fkbuff * fkb_p, void * dev_p, + uint32_t encap, uint32_t channel, + uint32_t phyHdr, BlogFcArgs_t *fc_args ) +{ + return _blog_finit(fkb_p, dev_p, encap, channel, phyHdr, fc_args); +} + +#if defined(CONFIG_BLOG) +extern BlogAction_t _blog_emit(void * nbuff_p, void * dev_p, + uint32_t encap, uint32_t channel, + uint32_t phyHdr, BlogFcArgs_t *fc_args); + +static inline BlogAction_t blog_emit_args(void * nbuff_p, void * dev_p, + uint32_t encap, uint32_t channel, + uint32_t phyHdr, BlogFcArgs_t *fc_args) +{ + if ( nbuff_p == NULL ) return PKT_NORM; + if ( !IS_SKBUFF_PTR(nbuff_p) ) return PKT_NORM; + // OK, this is something worth looking at, call real function + return ( _blog_emit(nbuff_p, dev_p, encap, channel, phyHdr, fc_args) ); +} + +static inline BlogAction_t blog_emit(void * nbuff_p, void * dev_p, + uint32_t encap, uint32_t channel, + uint32_t phyHdr) +{ + BlogFcArgs_t fc_args; + memset(&fc_args, 0, sizeof(BlogFcArgs_t)); + return ( blog_emit_args(nbuff_p, dev_p, encap, channel, phyHdr, &fc_args) ); +} + +#else +BlogAction_t blog_emit( void * nbuff_p, void * dev_p, + uint32_t encap, uint32_t channel, uint32_t phyHdr ); + +BlogAction_t blog_emit_args( void * nbuff_p, void * dev_p, + uint32_t encap, uint32_t channel, uint32_t phyHdr, + BlogFcArgs_t *fc_args); +#endif + +/* + * blog_iq_prio determines the Ingress QoS priority of the packet + */ +extern int blog_iq_prio(struct sk_buff * skb_p, void * dev_p, + uint32_t encap, uint32_t channel, uint32_t phyHdr); +/* + *------------------------------------------------------------------------------ + * blog_activate(): static configuration function of blog application + * pass a filled blog to the hook for configuration + *------------------------------------------------------------------------------ + */ +#if defined(CONFIG_BLOG) +extern BlogActivateKey_t *blog_activate( Blog_t * blog_p, BlogTraffic_t traffic ); +#else +extern uint32_t blog_activate( Blog_t * blog_p, BlogTraffic_t traffic ); +#endif + +/* + *------------------------------------------------------------------------------ + * blog_deactivate(): static deconfiguration function of blog application + *------------------------------------------------------------------------------ + */ +extern Blog_t * blog_deactivate( BlogActivateKey_t key, BlogTraffic_t traffic ); + +/* + * ----------------------------------------------------------------------------- + * User defined filter invoked invoked in the rx hook. A user may override the + * Blog action defined by the client. To enable the invocation of this API + * in blog_finit, ensure that CC_BLOG_SUPPORT_USER_FILTER is enabled. Also, a + * network device driver may directly invoke blog_filter() to override PKT_BLOG + * and return PKT_NORM (by releasing the associated Blog_t). + * ----------------------------------------------------------------------------- + */ +extern BlogAction_t blog_filter(Blog_t * blog_p); + +/* + * ----------------------------------------------------------------------------- + * Section 5. Binding Blog client applications: + * + * Blog defines three hooks: + * + * RX Hook: If this hook is defined then blog_init() will pass the packet to + * the Rx Hook using the FkBuff_t context. L1 and encap information + * are passed to the receive hook. The private network device context + * may be extracted using the passed net_device object, if needed. + * + * TX Hook: If this hook is defined then blog_emit() will check to see whether + * the NBuff has a Blog_t, and if so pass the NBuff and Blog to the + * bound Tx hook. + * + * NotifHook: When blog_notify is invoked, the bound hook is invoked. Based on + * event type the bound Blog client may perform a custom action. + * + * SC Hook: If this hook is defined, blog_activate() will pass a blog with + * necessary information for statical configuration. + * + * SD Hook: If this hook is defined, blog_deactivate() will pass a pointer + * to a network object with BlogActivateKey information. The + * respective flow entry will be deleted. + * + * QueryHook: When blog_query is invoked, the bound hook is invoked. Based on + * query type the bound Blog client will return result of query. + * ----------------------------------------------------------------------------- + */ +typedef union { + struct { + uint16_t QR_HOOK : 1; + uint16_t RX_HOOK : 1; + uint16_t TX_HOOK : 1; + uint16_t XX_HOOK : 1; + uint16_t SC_HOOK : 1; + uint16_t SD_HOOK : 1; + uint16_t FA_HOOK : 1; + uint16_t FD_HOOK : 1; + uint16_t PA_HOOK : 1; + uint16_t BM_HOOK : 1; + uint16_t reserved : 6; + } bmap; + uint16_t hook_info; +} BlogBind_t; + +typedef BlogAction_t (* BlogDevRxHook_t)(struct fkbuff *fkb_p, void * dev_p, + BlogFcArgs_t * args); + +typedef BlogAction_t (* BlogDevTxHook_t)(struct sk_buff *skb_p, void * dev_p, + uint32_t encap, uint32_t blogHash, BlogFcArgs_t * args); + +typedef int (* BlogNotifyHook_t)(blog_notify_api_t blog_notify_api, + BlogNotify_t notification, + void * net_p, unsigned long param1, unsigned long param2, + blog_notify_async_cb_fn_t notify_cb_fn, void *notify_cb_data_p); + +typedef int (* BlogQueryHook_t)(BlogQuery_t query, void * net_p, + uint32_t param1, uint32_t param2, unsigned long param3); + +typedef BlogActivateKey_t * (* BlogScHook_t)(Blog_t * blog_p, BlogTraffic_t traffic); + +typedef Blog_t * (* BlogSdHook_t)(BlogActivateKey_t key, BlogTraffic_t traffic); + +typedef void (* BlogFaHook_t)(void *ct_p, BlogFlowEventInfo_t info, BlogFlowEventType_t type); + +typedef void (* BlogFdHook_t)(void *ct_p, BlogFlowEventInfo_t info, BlogFlowEventType_t type); + +typedef BlogAction_t (* BlogPaHook_t)(struct fkbuff * fkb_p, void * dev_p, + uint32_t encap, uint32_t channel, uint32_t phyHdr); + +typedef int (* BlogBitMapHook_t)(uint32_t bitmap_idx, uint32_t *dst_p, uint32_t dst_size_words); + +extern int blog_get_hw_accel(void); +extern void blog_bind(BlogDevRxHook_t rx_hook, /* Client Rx netdevice handler*/ + BlogDevTxHook_t tx_hook, /* Client Tx netdevice handler*/ + BlogNotifyHook_t xx_hook, /* Client notification handler*/ + BlogQueryHook_t qr_hook, /* Client query handler */ + BlogBitMapHook_t blog_bm, /* Mcast BitMap copy handler */ + BlogBind_t bind + ); + +extern void blog_bind_config(BlogScHook_t sc_hook, /* Client static config handler*/ + BlogSdHook_t sd_hook, /* Client static deconf handler*/ + BlogBind_t bind + ); + +void blog_bind_packet_accelerator( BlogPaHook_t blog_pa, BlogBind_t bind ); +int blog_flowevent_register_notifier(struct notifier_block *nb); +int blog_flowevent_unregister_notifier(struct notifier_block *nb); + +/* + *------------------------------------------------------------------------------ + * blog notify event + *------------------------------------------------------------------------------ + */ +typedef struct { + struct dll_t node; /* First element implements dll */ + blog_notify_evt_type_t evt_type; + void *net_p; + unsigned long param1; + unsigned long param2; + blog_notify_async_cb_fn_t notify_cb_fn; + void *notify_cb_data_p; +} ____cacheline_aligned blog_notify_evt_t; + +/* + * ----------------------------------------------------------------------------- + * Section 6. Miscellanous + * ----------------------------------------------------------------------------- + */ + +/* Dump a Blog_t object */ +extern void blog_hw_formatted_dump(Blog_t *blog_p); + +/* Logging of L2|L3 headers */ +extern void blog(struct sk_buff * skb_p, BlogDir_t dir, BlogEncap_t encap, + size_t len, void * data_p); + +/* Dump a Blog_t object */ +extern void blog_dump(Blog_t * blog_p); + +/* Get the minimum Tx MTU for a blog */ +uint16_t blog_getTxMtu(Blog_t * blog_p); + +/* + * Lock and unlock the blog layer. This is used to reduce the number of + * times the blog lock must be acquired and released during bulk rx processing. + * See also blog_finit_locked. + */ +extern void blog_lock(void); +extern void blog_unlock(void); + +/* + * Per packet basis modification feature + */ +#define BLOG_MAX_FEATURES 8 + +#define BLOG_LEN_PARAM_INDEX 0 +#define BLOG_DSCP_PARAM_INDEX 1 +#define BLOG_TOS_PARAM_INDEX 2 + +#define BLOG_MAX_LEN_TBLSZ 8 +#define BLOG_MAX_DSCP_TBLSZ 64 +#define BLOG_MAX_TOS_TBLSZ 256 + +#define BLOG_LEN_PARAM_NUM 4 +#define BLOG_MAX_PARAM_NUM 4 + +#define BLOG_MIN_LEN_INDEX 0 +#define BLOG_MAX_LEN_INDEX 1 +#define BLOG_ORIGINAL_MARK_INDEX 2 +#define BLOG_TARGET_MARK_INDEX 3 + +#define BLOG_MATCH_DSCP_INDEX 0 +#define BLOG_TARGET_DSCP_INDEX 1 + +#define BLOG_MATCH_TOS_INDEX 0 +#define BLOG_TARGET_TOS_INDEX 1 + +#define BLOG_INVALID_UINT8 ((uint8_t)(-1)) +#define BLOG_INVALID_UINT16 ((uint16_t)(-1)) +#define BLOG_INVALID_UINT32 ((uint32_t)(-1)) + +extern int blog_set_ack_tbl(uint32_t val[]); +extern int blog_clr_ack_tbl(void); +extern int blog_set_len_tbl(uint32_t val[]); +extern int blog_clr_len_tbl(void); +extern int blog_set_dscp_tbl(uint8_t idx, uint8_t val); +extern int blog_clr_dscp_tbl(void); +extern int blog_set_tos_tbl(uint8_t idx, uint8_t val); +extern int blog_clr_tos_tbl(void); +extern int blog_pre_mod_hook(Blog_t *blog_p, void *nbuff_p); +extern int blog_post_mod_hook(Blog_t *blog_p, void *nbuff_p); + +#if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE) +#define BLOG_GRE_RCV_NOT_GRE 2 +#define BLOG_GRE_RCV_NO_SEQNO 1 +#define BLOG_GRE_RCV_IN_SEQ 0 +#define BLOG_GRE_RCV_NO_TUNNEL -1 +#define BLOG_GRE_RCV_FLAGS_MISSMATCH -2 +#define BLOG_GRE_RCV_CHKSUM_ERR -3 +#define BLOG_GRE_RCV_OOS_LT -4 +#define BLOG_GRE_RCV_OOS_GT -5 + +extern int blog_gre_rcv( struct fkbuff *fkb_p, void * dev_p, uint32_t h_proto, + void **tunl_pp, uint32_t *pkt_seqno_p); +extern void blog_gre_xmit( struct sk_buff *skb_p, uint32_t h_proto ); +#endif + +#if defined(CONFIG_ACCEL_PPTP) +#define BLOG_PPTP_ENCRYPTED 3 +#define BLOG_PPTP_RCV_NOT_PPTP 2 +#define BLOG_PPTP_RCV_NO_SEQNO 1 +#define BLOG_PPTP_RCV_IN_SEQ 0 +#define BLOG_PPTP_RCV_NO_TUNNEL -1 +#define BLOG_PPTP_RCV_FLAGS_MISSMATCH -2 +#define BLOG_PPTP_RCV_CHKSUM_ERR -3 +#define BLOG_PPTP_RCV_OOS_LT -4 +#define BLOG_PPTP_RCV_OOS_GT -5 +extern int blog_pptp_rcv( struct fkbuff *fkb_p, uint32_t h_proto, + uint32_t *rcv_pktSeq); +extern void blog_pptp_xmit( struct sk_buff *skb_p, uint32_t h_proto ); +#endif + +#define BLOG_L2TP_RCV_TUNNEL_FOUND 1 +#define BLOG_L2TP_RCV_NO_TUNNEL 0 + +#define BLOG_INCLUDE_VIRTUAL_DEVS 1 + +void blog_get_dev_stats(void *dev_p, void *bStats_p); +void blog_clr_dev_stats(void *dev_p); +void blog_get_dev_running_stats(void *dev_p, void * const bStats_p); +void blog_get_dev_running_stats_wlan(void *dev_p, void * const bStats_p); /* Remove once WLAN falls in place */ +void blog_add_dev_accelerated_stats(void *dev_p, void *stats64_p); + +typedef struct { + wait_queue_head_t wqh; + unsigned long work_avail; +#define BLOG_WORK_AVAIL (1<<0) + spinlock_t wakeup_lock; + bool wakeup_done; +} wq_info_t; + +#define BLOG_WAKEUP_WORKER_THREAD(x, mask) \ +do { \ + if ( !((x)->work_avail & mask) ) { \ + (x)->work_avail |= mask; \ + wake_up_interruptible(&((x)->wqh)); \ + } \ +} while (0) + +/*wake up with spinlock to avoid preemption/bh processing between + *setting work_avail & wakeup + */ +#define BLOG_WAKEUP_WORKER_THREAD_NO_PREEMPT(x, mask) \ +do { \ + spin_lock_bh(&((x)->wakeup_lock)); \ + BLOG_WAKEUP_WORKER_THREAD(x, mask); \ + (x)->wakeup_done = true; \ + spin_unlock_bh(&((x)->wakeup_lock)); \ +} while (0) + + +void blog_fold_stats(BlogStats_t * const d, + const BlogStats_t * const s); +int blog_copy_mcast_client_bitmap(uint16_t bitmap_idx, uint32_t *dst_p, uint32_t dst_size_words); + +void *blog_mcast_dev_realloc(Blog_t *mblog_p, uint8_t new); +void blog_mcast_dev_free(Blog_t *mblog_p); +int blog_mcast_find_matching_dev(Blog_t *mblog_p, void *dev_p, int8_t delta); +int blog_mcast_add_rx_dev(Blog_t *mblog_p, Blog_t *cblog_p); +void blog_mcast_del_rx_dev(Blog_t *mblog_p, Blog_t *cblog_p); +int blog_mcast_add_tx_dev(Blog_t *mblog_p, Blog_t *cblog_p); +void blog_mcast_del_tx_dev(Blog_t *mblog_p, Blog_t *cblog_p); +void blog_mcast_del_all_devs(Blog_t *mblog_p); + +typedef struct blog_ctx { + uint32_t blog_total; + uint32_t blog_avail; + uint32_t blog_mem_fails; + uint32_t blog_extends; + uint32_t blog_extend_fails; + blog_info_stats_t info_stats; + blog_skip_reason_t blog_skip_stats_table[blog_skip_reason_max]; + blog_free_reason_t blog_free_stats_table[blog_free_reason_max]; + uint32_t blog_dump; +} blog_ctx_t; + +#endif /* defined(__BLOG_H_INCLUDED__) */ + +#endif /* CONFIG_BCM_KF_BLOG */ diff --git a/include/linux/blog_net.h b/include/linux/blog_net.h new file mode 100644 index 0000000000000000000000000000000000000000..d875958dcfe2d38985993c8dc390a0f164c3adb2 --- /dev/null +++ b/include/linux/blog_net.h @@ -0,0 +1,849 @@ +#ifndef __BLOG_NET_H_INCLUDED__ +#define __BLOG_NET_H_INCLUDED__ + +/* +<:copyright-BRCM:2003:DUAL/GPL:standard + + Copyright (c) 2003 Broadcom + All Rights Reserved + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + +/* + ******************************************************************************* + * + * File Name : blog_net.h + * + * Description: + * + * Global definitions and declaration of Protocol Headers independent of OS as + * per IEEE and RFC standards. Inlined utilities for header access. + * + * CAUTION: All protocol header structures are declared for Big Endian access + * and are not compatible for a Little Endian machine. + * + * CAUTION: It is also assumed that the Headers are AT LEAST 16bit aligned. + * + ******************************************************************************* + */ + +#if defined(CONFIG_CPU_BIG_ENDIAN) +#define BE_DECL(declarations) declarations +#define BE_CODE(statements) do { statements } while (0) +#define LE_DECL(declarations) +#define LE_CODE(statements) NULL_STMT +#elif defined(CONFIG_CPU_LITTLE_ENDIAN) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) +#define BE_DECL(declarations) +#define BE_CODE(statements) NULL_STMT +#define LE_DECL(declarations) declarations +#define LE_CODE(statements) do { statements } while (0) +#else +#error "Compile: fix endianess in platform.h" +#endif + + +/*TODO rename these PHY types to BCM_XXXPHY */ +#undef BLOG_DECL +#define BLOG_DECL(x) x, +/* + *------------------------------------------------------------------------------ + * Denotes the type of physical interface and the presence of a preamble. + *------------------------------------------------------------------------------ + */ +typedef enum { + BLOG_DECL(BLOG_NOPHY) /* index 0 placeholder for non-bloggable interface */ + BLOG_DECL(BLOG_XTMPHY) + BLOG_DECL(BLOG_ENETPHY) + BLOG_DECL(BLOG_GPONPHY) + BLOG_DECL(BLOG_EPONPHY) + BLOG_DECL(BLOG_USBPHY) + BLOG_DECL(BLOG_WLANPHY) + BLOG_DECL(BLOG_MOCAPHY) + BLOG_DECL(BLOG_EXTRA1PHY) + BLOG_DECL(BLOG_LTEPHY) + BLOG_DECL(BLOG_SIDPHY) + BLOG_DECL(BLOG_TCP4_LOCALPHY) + BLOG_DECL(BLOG_SPU_DS) + BLOG_DECL(BLOG_SPU_US) + BLOG_DECL(BLOG_NETXLPHY) + BLOG_DECL(BLOG_SPDTST) + BLOG_DECL(BLOG_MAXPHY) +} BlogPhy_t; + +/* + *------------------------------------------------------------------------------ + * RFC 2684 header logging. + * CAUTION: 0'th enum corresponds to either header was stripped or zero length + * header. VC_MUX_PPPOA and VC_MUX_IPOA have 0 length RFC2684 header. + * PTM does not have an rfc2684 header. + *------------------------------------------------------------------------------ + */ +typedef enum { + BLOG_DECL(RFC2684_NONE) /* */ + BLOG_DECL(LLC_SNAP_ETHERNET) /* AA AA 03 00 80 C2 00 07 00 00 */ + BLOG_DECL(LLC_SNAP_ROUTE_IP) /* AA AA 03 00 00 00 08 00 */ + BLOG_DECL(LLC_ENCAPS_PPP) /* FE FE 03 CF */ + BLOG_DECL(VC_MUX_ETHERNET) /* 00 00 */ + BLOG_DECL(VC_MUX_IPOA) /* */ + BLOG_DECL(VC_MUX_PPPOA) /* */ + BLOG_DECL(PTM) /* */ + BLOG_DECL(RFC2684_MAX) +} Rfc2684_t; + +/*----- LinkType: First header type ------------------------------------------*/ +/* Used by network drivers to determine the Layer 1 encapsulation or LinkType */ +typedef enum { + BLOG_DECL(TYPE_ETH) /* LAN: ETH, WAN: EoA, MER, PPPoE */ + BLOG_DECL(TYPE_PPP) /* WAN: PPPoA */ + BLOG_DECL(TYPE_IP) /* WAN: IPoA */ +} BlogLinkType_t; + +#define BLOG_SET_PHYHDR(a, b) ( (((a) & 0xf) << 4) | ((b) & 0xf) ) +#define BLOG_GET_PHYTYPE(a) ( (a) & 0xf ) +#define BLOG_GET_PHYLEN(a) ( (a) >> 4 ) + +#define BLOG_PHYHDR_MASK 0xff +#define BLOG_SET_HW_ACT(a) ( ((a) & 0xf) << 8 ) +#define BLOG_GET_HW_ACT(a) ( (a) >> 8 ) + +/*----- ETH_TYPE: Standard well-defined Ethernet Encapsulations --------------*/ +#define BLOG_ETH_P_ETH_BRIDGING 0x6558 /* Transparent Ethernet bridging */ +#define BLOG_ETH_P_IPV4 0x0800 /* IPv4 in Ethernet */ +#define BLOG_ETH_P_ARP 0x0806 /* Address Resolution packet */ +#define BLOG_ETH_P_RARP 0x8035 /* Reverse ARP */ +#define BLOG_ETH_P_APPLTK_AARP 0x80F3 /* AppleTalk AARP */ +#define BLOG_ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */ +#define BLOG_ETH_P_8021AD 0x88A8 /* VLAN Stacking 802.1ad */ +#define BLOG_ETH_P_NOVELL 0x8137 /* Novell, Inc. */ +#define BLOG_ETH_P_IPV6 0x86DD /* Internet Protocol Version 6 */ +#define BLOG_ETH_P_MPLS_UC 0x8847 /* MPLS - Unicast */ +#define BLOG_ETH_P_MPLS_MC 0x8848 /* MPLS - Multicast */ +#define BLOG_ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */ +#define BLOG_ETH_P_PPP_DIS 0x8863 /* PPPoE Discovery */ +#define BLOG_ETH_P_PPP_SES 0x8864 /* PPPoE Session */ +#define BLOG_ETH_JUMBO_FRAME 0x8870 /* Jumbo frame indicator */ +#define BLOG_ETH_P_BRCM6TAG 0x8874 /* BRCM Switch Hdr : 6 byte */ +#define BLOG_ETH_P_BRCM4TAG 0x888A /* BRCM Switch Hdr : 4 byte */ +#define BLOG_ETH_P_PAUSE 0x8808 /* IEEE Pause frames. 802.3 31B */ +#define BLOG_ETH_P_SLOW 0x8809 /* Slow Protocol. See 802.3ad 43B */ +#define BLOG_ETH_P_8021AG 0x8902 /* 802.1ag Connectivity FaultMgmt */ + /* ITU-T recomm Y.1731 (OAM) */ +#define BLOG_ETH_FCOE 0x8906 /* Fibre Channel over Ethernet */ +#define BLOG_ETH_FCOE_INIT 0x8914 /* FCoE Initialization Protocol */ +#define BLOG_ETH_QINQ1 0x9100 /* 802.1Q in Q, alternate 1 */ +#define BLOG_ETH_QINQ2 0x9200 /* 802.1Q in Q, alternate 2 */ + +/*----- PPP_TYPE: Standard well-defined PPP Encapsulations -------------------*/ +#define BLOG_PPP_IPV4 0x0021 /* IPv4 in PPP */ +#define BLOG_PPP_IPCP 0x8021 /* IP Control Protocol */ +#define BLOG_PPP_LCP 0xC021 /* Link Control Protocol */ +#define BLOG_PPP_MP 0x003D /* Multilink protocol */ +#define BLOG_PPP_IPV6 0x0057 /* IPv6 in PPP */ +#define BLOG_PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ +#define BLOG_PPP_MPLSCP 0x80FD /* MPLS Control Protocol??? */ +#define BLOG_PPP_MPLS_UC 0x0281 /* MPLS - Unicast */ +#define BLOG_PPP_MPLS_MC 0x0283 /* MPLS - Multicast */ + +#define BLOG_GRE_PPP 0x880B /* PPTP: PPP in GRE Tunnel */ + +/*----- IPPROTO: Standard well-defined IP Encapsulations ---------------------*/ +#define BLOG_IPPROTO_HOPOPTV6 0 /* IPv6 ext: Hop-by-Hop Option Header */ +#define BLOG_IPPROTO_ICMP 1 /* Internet Control Message Protocol */ +#define BLOG_IPPROTO_IGMP 2 /* Internet Group Management Protocol */ +#define BLOG_IPPROTO_IPIP 4 /* IPIP tunnels e.g. 4in6 */ +#define BLOG_IPPROTO_TCP 6 /* Transmission Control Protocol */ +#define BLOG_IPPROTO_EGP 8 /* Exterior Gateway Protocol */ +#define BLOG_IPPROTO_UDP 17 /* User Datagram Protocol */ +#define BLOG_IPPROTO_IPV6 41 /* IPv6-in-IPv4 tunnelling */ +#define BLOG_IPPROTO_ROUTING 43 /* IPv6 ext: Routing Header */ +#define BLOG_IPPROTO_FRAGMENT 44 /* IPv6 ext: Fragmentation Header */ +#define BLOG_IPPROTO_RSVP 46 /* RSVP Protocol */ +#define BLOG_IPPROTO_GRE 47 /* Cisco GRE tunnels (rfc 1701,1702) */ +#define BLOG_IPPROTO_ESP 50 /* Encapsulation Security Payload */ +#define BLOG_IPPROTO_AH 51 /* Authentication Header Protocol */ +#define BLOG_IPPROTO_ICMPV6 58 /* IPv6 ext: ICMPv6 Header */ +#define BLOG_IPPROTO_NONE 59 /* IPv6 ext: NONE */ +#define BLOG_IPPROTO_DSTOPTS 60 /* IPv6 ext: Destination Options Hdr */ +#define BLOG_IPPROTO_ANY_HOST_INTERNAL_PROTO 61 /* Any host internel proto */ +#define BLOG_IPPROTO_MTP 92 /* IPv6 ext: Mcast Transport Protocol */ +#define BLOG_IPPROTO_ENCAP 98 /* IPv6 ext: Encapsulation Header */ +#define BLOG_IPPROTO_PIM 103 /* Protocol Independent Multicast */ +#define BLOG_IPPROTO_COMP 108 /* Compression Header Protocol */ +#define BLOG_IPPROTO_ANY_0HOP 114 /* Any Zero HOP */ +#define BLOG_IPPROTO_SCTP 132 /* Stream Control Transport Protocol */ +#define BLOG_IPPROTO_UDPLITE 136 /* UDP-Lite (RFC 3828) */ + +#define BLOG_IPPROTO_UNASSIGN_B 141 /* Begin of unassigned range */ +#define BLOG_IPPROTO_UNASSIGN_E 252 /* End of unassigned range */ +#define BLOG_IPPROTO_RSVD_EXPT1 253 /* Reserved for experimentation */ +#define BLOG_IPPROTO_RSVD_EXPT2 254 /* Reserved for experimentation */ +#define BLOG_IPPROTO_RAW 255 /* Raw IP Packets */ + + +/* IGRS/UPnP using Simple Service Discovery Protocol SSDP over HTTPMU */ +#define BLOG_HTTP_MCAST_UDP_DSTPORT 1900 + +/* Known L4 Ports */ +#define BLOG_DNS_SERVER_PORT 53 +#define BLOG_DHCP_SERVER_PORT 67 +#define BLOG_DHCP_CLIENT_PORT 68 + +/*----- Ethernet IEEE 802.3 definitions ------------------------------------- */ +#define BLOG_LLC_SAP_SNAP (0xAA) +#define BLOG_LLC_SNAP_8023_DSAP (BLOG_LLC_SAP_SNAP) +#define BLOG_LLC_SNAP_8023_SSAP (BLOG_LLC_SAP_SNAP) +#define BLOG_LLC_SNAP_8023_Ctrl (0x3) +#define BLOG_LLC_SNAP_8023_LEN 8 + +#define BLOG_ETH_ADDR_LEN 6 +#define BLOG_ETH_TYPE_LEN sizeof(uint16_t) +#define BLOG_ETH_HDR_LEN ((BLOG_ETH_ADDR_LEN * 2) + BLOG_ETH_TYPE_LEN) +#define BLOG_ETH_TYPE_MIN 1536 + +#define BLOG_ETH_MIN_LEN 60 +#define BLOG_ETH_FCS_LEN 4 +#define BLOG_ETH_MTU_LEN 0xFFFF /* Initial minMtu value */ + +#define BLOG_ETH_ADDR_FMT "[%02X:%02X:%02X:%02X:%02X:%02X]" +#define BLOG_ETH_ADDR(e) e.u8[0],e.u8[1],e.u8[2],e.u8[3],e.u8[4],e.u8[5] + +typedef union BlogEthAddr { + uint8_t u8[BLOG_ETH_ADDR_LEN]; + uint16_t u16[BLOG_ETH_ADDR_LEN/sizeof(uint16_t)]; +} BlogEthAddr_t; + +typedef struct BlogEthHdr { + union { + uint8_t u8[BLOG_ETH_HDR_LEN]; + uint16_t u16[BLOG_ETH_HDR_LEN/sizeof(uint16_t)]; + struct { + BlogEthAddr_t macDa; + BlogEthAddr_t macSa; + /* + * CAUTION: Position of ethType field of an Ethernet header depends on + * the presence and the number of VLAN Tags + * E.g. A single tagged Ethernet frame will have the ethType at offset 16. + */ + uint16_t ethType; /* or length */ + }; + }; +} BlogEthHdr_t; + +/* 16bit aligned access MAC Address functgions */ +static inline int blog_is_zero_eth_addr(uint8_t * addr_p) +{ + uint16_t * u16_p = (uint16_t *)addr_p; /* assert u16_p is 16bit aligned */ + return ( (u16_p[0] & u16_p[1] & u16_p[2]) == 0x0000 ); +} + +static inline int blog_is_bcast_eth_addr(uint8_t * addr_p) +{ + uint16_t * u16_p = (uint16_t *)addr_p; /* assert u16_p is 16bit aligned */ + return ( (u16_p[0] & u16_p[1] & u16_p[2]) == 0xFFFF ); +} + +/* Caution an IP mcast over PPPoE need not have a mcast MacDA */ +static inline int blog_is_mcast_eth_addr(uint8_t * addr_p) +{ +#if 1 + return *(addr_p+0) & 0x01; +#else /* Multicast (e.g. over PPPoE) may use unicast MacDA */ + uint16_t * u16_p = (uint16_t *)addr_p; /* assert u16_p is 16bit aligned */ + if ( ((u16_p[0] == 0x0100) /* IPv4: 01:00:5E:`1b0 */ + && (*(addr_p+2) == 0x5e) && ((*(addr_p+3) & 0x80) == 0) ) + || ( u16_p[0] == 0x3333) /* IPv6: 33:33 */ + ) + return 1; + else + return 0; +#endif +} + +static inline int blog_cmp_eth_addr(uint8_t * addr1_p, uint8_t * addr2_p) +{ + uint16_t *a1 = (uint16_t *)addr1_p; + uint16_t *a2 = (uint16_t *)addr2_p; + return ( ((a1[0] ^ a2[0]) | (a1[1] ^ a2[1]) | (a1[2] ^ a2[2])) != 0 ); +} + + +/*----- 6Byte Brcm6Hdr layout for 5397/98 Switch Management Port Tag ---------*/ +#define BLOG_BRCM6_HDR_LEN 6 + +typedef struct BlogBrcm6Hdr { + union { + uint8_t u8[BLOG_BRCM6_HDR_LEN]; + uint16_t u16[BLOG_BRCM6_HDR_LEN/sizeof(uint16_t)]; + /* + * egress: opcode:3, fbcount:14, rsvd:11, srcPortId:4 + * ingress_port opcode:3, rsvd:25, dstPortId:4 + * ingress_map opcode:3, rsvd:20, fwdMap:9 + */ + }; +} BlogBrcm6Hdr_t; + + +/*----- 4Byte Brcm4Hdr layout for 53115 Switch Management Port Tag -----------*/ +#define BLOG_BRCM4_HDR_LEN 4 + +typedef struct BlogBrcm4Hdr { + union { + uint8_t u8[BLOG_BRCM4_HDR_LEN]; + uint16_t u16[BLOG_BRCM4_HDR_LEN/sizeof(uint16_t)]; + /* + * egress opcode:3, rsvd:13, rsvd2:2, + * flooding:1, snooping:1, protocol:1, switching:1 + * learning:1, mirroring:1, tclass:3, srcpid:5 + * ingress opcode:3, tclass:3, + * tagenforce:2, rsvd:1, dstmap:23 + */ + }; +} BlogBrcm4Hdr_t; + +/*----- Composite Ethernet with BRCM Tag -------------------------------------*/ + +#define BLOG_ETHBRCM6_HDR_LEN (BLOG_ETH_HDR_LEN + BLOG_BRCM6_HDR_LEN) +#define BLOG_ETHBRCM4_HDR_LEN (BLOG_ETH_HDR_LEN + BLOG_BRCM4_HDR_LEN) + +typedef struct BlogEthBrcm6Hdr { + union { + uint8_t u8[BLOG_ETHBRCM6_HDR_LEN]; + uint16_t u16[BLOG_ETHBRCM6_HDR_LEN/sizeof(uint16_t)]; + struct { + BlogEthAddr_t macDa; + BlogEthAddr_t macSa; + BlogBrcm6Hdr_t brcm6; + uint16_t ethType; + }; + }; +} BlogEthBrcm6Hdr_t; + +typedef struct BlogEthBrcm4Hdr { + union { + uint8_t u8[BLOG_ETHBRCM4_HDR_LEN]; + uint16_t u16[BLOG_ETHBRCM4_HDR_LEN/sizeof(uint16_t)]; + struct { + BlogEthAddr_t macDa; + BlogEthAddr_t macSa; + BlogBrcm4Hdr_t brcm4; + uint16_t ethType; + }; + }; +} BlogEthBrcm4Hdr_t; + + +/*----- Vlan IEEE 802.1Q definitions -----------------------------------------*/ +#define BLOG_VLAN_HDR_LEN 4 +#define BLOG_VLAN_HDR_FMT "[0x%08X] tpid<0x%04X> tci<0x%04X> "\ + "pbit<%u> dei<%u> vid<0x%03X>" +#define BLOG_VLAN_HDR(v) v.u32[0], v.tpid, v.tci.u16[0], \ + v.tci.pbits, v.tci.dei, v.tci.vid + +typedef struct BlogVlanTci { + union { + uint8_t u8[sizeof(uint16_t)]; + uint16_t u16[1]; + struct { + BE_DECL( uint16_t pbits:3; uint16_t dei:1; uint16_t vid:12; ) + LE_DECL( uint16_t vid:12; uint16_t dei:1; uint16_t pbits:3; ) + }; + }; +} BlogVlanTci_t; + +typedef struct BlogVlanHdr { + union { + uint8_t u8[BLOG_VLAN_HDR_LEN]; + uint16_t u16[BLOG_VLAN_HDR_LEN/sizeof(uint16_t)]; + uint32_t u32[BLOG_VLAN_HDR_LEN/sizeof(uint32_t)]; + struct { + uint16_t tpid; BlogVlanTci_t tci; /* u8[ 88, A8, EA, AA ] */ + }; + }; +} BlogVlanHdr_t; + + +/*----- PPPoE + PPP Header layout. PPPoE RFC 2516, PPP RFC 1661 --------------*/ +#define BLOG_PPPOE_HDR_LEN 8 /* Including PPP Header "PPP Type" */ +#define BLOG_PPP_HDR_LEN sizeof(uint16_t) +#define BLOG_PPPOE_HDR_FMT "[0x%08X 0x%08X] ver<%u> type<%u> code<0x%02X>"\ + " sId<0x%04X> len<%u> pppType<0x%04X>" +#define BLOG_PPPOE_HDR(p) p.u32[0], p.u32[1], p.ver, p.type, p.code,\ + p.sId, p.len, p.pppType + +typedef uint16_t BlogPppHdr_t; + +typedef struct BlogPppoeHdr { /* includes 2 byte PPP Type */ + union { + uint8_t u8[BLOG_PPPOE_HDR_LEN]; + uint16_t u16[BLOG_PPPOE_HDR_LEN/sizeof(uint16_t)]; + uint32_t u32[BLOG_PPPOE_HDR_LEN/sizeof(uint32_t)]; + struct { + BE_DECL( uint16_t ver:4; uint16_t type:4; uint16_t code:8; ) + LE_DECL( uint16_t code:8; uint16_t type:4; uint16_t ver:4; ) + uint16_t sId; uint16_t len; BlogPppHdr_t pppType; + }; + }; +} BlogPppoeHdr_t; + + +/*----- Multi Protocol Label Switiching Architecture: RFC 3031 ----------------- + * + * 20b-label, 3b-tos, 1b-Stack, 8b-TTL + * StackBit==1? if label==0 then next is IPV4, if label==1 then next is IPV6 + *------------------------------------------------------------------------------ + */ +#define BLOG_MPLS_HDR_LEN 4 + +typedef struct BlogMplsHdr { + union { + uint8_t u8[BLOG_MPLS_HDR_LEN]; + uint16_t u16[BLOG_MPLS_HDR_LEN/sizeof(uint16_t)]; + uint32_t u32[BLOG_MPLS_HDR_LEN/sizeof(uint32_t)]; + struct { + BE_DECL( uint32_t label:20; uint32_t cos:3; uint32_t sbit:1; uint32_t ttl:8; ) + LE_DECL( uint32_t ttl:8; uint32_t sbit:1; uint32_t cos:3; uint32_t label:20; ) + }; + }; +} BlogMplsHdr_t; + + +/*----- IPv4: RFC 791 definitions --------------------------------------------*/ +#define BLOG_IPV4_HDR_LEN 20 /* Not including IP Options */ +#define BLOG_IPV4_ADDR_LEN 4 +#define BLOG_IPV4_HDR_FMT "[0x%08X] ver<%u> ihl<%u> tos<0x%02X> len<%u> "\ + "[0x%08X] id<%u> df<%u> mf<%u> "\ + "fragOffset<0x%04X> [0x%08X] "\ + "ttl<%u> proto<%u> chkSum<0x%04X> "\ +#define BLOG_IPV4_HDR(i) i.u32[0], i.ver, i.ihl, i.tos, i.len, \ + i.u32[1], i.id, i.df, i.mf, i.fragOffset,\ + i.u32[2], i.ttl, i.proto, i.chkSum, +#define BLOG_IPTOS2DSCP(tos) ((tos) >> 2) +#define BLOG_IPDSCP2TOS(dscp) ((dscp) << 2) + +#define BLOG_IPV4_ADDR_FMT "<%03u.%03u.%03u.%03u>" +#define BLOG_IPV4_ADDR_PORT_FMT "<%03u.%03u.%03u.%03u:%u>" +#define BLOG_IPV4_ADDR(ip) ((uint8_t*)&ip)[0], ((uint8_t*)&ip)[1], \ + ((uint8_t*)&ip)[2], ((uint8_t*)&ip)[3] + +#if defined(CONFIG_CPU_BIG_ENDIAN) +#define BLOG_IPV4_ADDR_HOST(ip) ((uint8_t*)&ip)[0], ((uint8_t*)&ip)[1], \ + ((uint8_t*)&ip)[2], ((uint8_t*)&ip)[3] +#elif defined(CONFIG_CPU_LITTLE_ENDIAN) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) +#define BLOG_IPV4_ADDR_HOST(ip) ((uint8_t*)&ip)[3], ((uint8_t*)&ip)[2], \ + ((uint8_t*)&ip)[1], ((uint8_t*)&ip)[0] +#endif + +typedef union BlogIpv4Addr { + uint8_t u8[BLOG_IPV4_ADDR_LEN]; + uint16_t u16[BLOG_IPV4_ADDR_LEN/sizeof(uint16_t)]; + uint32_t u32[BLOG_IPV4_ADDR_LEN/sizeof(uint32_t)]; +} BlogIpv4Addr_t; + +#define BLOG_IP_FLAG_CE 0x8000 /* Congestion */ +#define BLOG_IP_FLAG_DF 0x4000 /* Do Not Fragment */ +#define BLOG_IP_FLAG_MF 0x2000 /* More Fragment */ +#define BLOG_IP_FRAG_OFFSET 0x1FFF + +typedef struct BlogIpv4Hdr { + union { + uint8_t u8[BLOG_IPV4_HDR_LEN]; + uint16_t u16[BLOG_IPV4_HDR_LEN/sizeof(uint16_t)]; + uint32_t u32[BLOG_IPV4_HDR_LEN/sizeof(uint32_t)]; + struct { + union { + struct { + BE_DECL( uint8_t ver:4; uint8_t ihl:4; ) + LE_DECL( uint8_t ihl:4; uint8_t ver:4; ) + }; + uint8_t ver_ihl; + }; + uint8_t tos; uint16_t len; + uint16_t id; + union { + uint16_t flagsFrag; + struct { + BE_DECL( uint16_t cong:1; uint16_t df:1; + uint16_t moreFrag:1; uint16_t fragOffset:13; ) + LE_DECL( uint16_t fragOffset:13; uint16_t moreFrag:1; + uint16_t df:1; uint16_t cong:1; ) + }; + }; + uint8_t ttl; uint8_t proto; uint16_t chkSum; + BlogIpv4Addr_t sAddr; + BlogIpv4Addr_t dAddr; + }; + }; +} BlogIpv4Hdr_t; + + +/*----- IPv6: RFC 2460 RFC 3513 definitions ----------------------------------*/ +/* + * Well know IPv6 Address prefixes + * Multicast: FFXX:: + * Site local: FEC0:: + * Link Local: FE80:: + * Ucast 6to4: 2002:: + */ +#define BLOG_IPV6_HDR_LEN 40 +#define BLOG_IPV6_ADDR_LEN 16 + +#define BLOG_IPV6_ADDR_FMT "<%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x>" +#define BLOG_IPV6_ADDR_PORT_FMT "<%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%u>" +#define BLOG_IPV6_ADDR(ip) \ + ntohs(((uint16_t*)&ip)[0]), ntohs(((uint16_t*)&ip)[1]), \ + ntohs(((uint16_t*)&ip)[2]), ntohs(((uint16_t*)&ip)[3]), \ + ntohs(((uint16_t*)&ip)[4]), ntohs(((uint16_t*)&ip)[5]), \ + ntohs(((uint16_t*)&ip)[6]), ntohs(((uint16_t*)&ip)[7]) + +typedef union BlogIpv6Addr { + uint8_t u8[BLOG_IPV6_ADDR_LEN]; + uint16_t u16[BLOG_IPV6_ADDR_LEN/sizeof(uint16_t)]; + uint32_t u32[BLOG_IPV6_ADDR_LEN/sizeof(uint32_t)]; +} BlogIpv6Addr_t; + +typedef struct BlogIpv6Hdr { + union { + uint8_t u8[BLOG_IPV6_HDR_LEN]; + uint16_t u16[BLOG_IPV6_HDR_LEN/sizeof(uint16_t)]; + uint32_t u32[BLOG_IPV6_HDR_LEN/sizeof(uint32_t)]; + struct { + /* ver_tos bits -> ver 4: tos 8: flowlblHi 4 + using bit field results in unaligned access */ + uint16_t ver_tos; uint16_t flowLblLo; + uint16_t len; uint8_t nextHdr; uint8_t hopLmt; + BlogIpv6Addr_t sAddr; + BlogIpv6Addr_t dAddr; + }; + }; +} BlogIpv6Hdr_t; + +#define BLOG_IPV6EXT_HDR_LEN 8 /* multiple of 8 octets */ +typedef struct BlogIpv6ExtHdr { + union { + uint8_t u8[BLOG_IPV6EXT_HDR_LEN]; + uint16_t u16[BLOG_IPV6EXT_HDR_LEN/sizeof(uint16_t)]; + uint32_t u32[BLOG_IPV6EXT_HDR_LEN/sizeof(uint32_t)]; + struct { + uint8_t nextHdr; uint8_t hdrLen; uint16_t data16; + uint32_t data32; + }; + }; +} BlogIpv6ExtHdr_t; + + +/*----- Transmission Control Protocol: RFC 793 definitions -------------------*/ + +#define BLOG_TCP_HDR_LEN 20 + +#define TCPH_DOFF(t) (((htons(t->offFlags.u16)) >> 12) & 0xF) +#define TCPH_CWR(t) (((htons(t->offFlags.u16)) >> 7) & 0x1) +#define TCPH_ECE(t) (((htons(t->offFlags.u16)) >> 6) & 0x1) +#define TCPH_URG(t) (((htons(t->offFlags.u16)) >> 5) & 0x1) +#define TCPH_ACK(t) (((htons(t->offFlags.u16)) >> 4) & 0x1) +#define TCPH_PSH(t) (((htons(t->offFlags.u16)) >> 3) & 0x1) +#define TCPH_RST(t) (((htons(t->offFlags.u16)) >> 2) & 0x1) +#define TCPH_SYN(t) (((htons(t->offFlags.u16)) >> 1) & 0x1) +#define TCPH_FIN(t) (((htons(t->offFlags.u16)) >> 0) & 0x1) + +typedef struct BlogTcpOffFlags { + union { + uint16_t u16; + struct { uint8_t off; uint8_t flags; }; + struct { + BE_DECL( + uint16_t dOff: 4; + uint16_t res1: 4; + uint16_t cwr : 1; + uint16_t ece : 1; + uint16_t urg : 1; + uint16_t ack : 1; + uint16_t psh : 1; + uint16_t rst : 1; + uint16_t syn : 1; + uint16_t fin : 1; + ) + LE_DECL( + uint16_t fin : 1; + uint16_t syn : 1; + uint16_t rst : 1; + uint16_t psh : 1; + uint16_t ack : 1; + uint16_t urg : 1; + uint16_t ece : 1; + uint16_t cwr : 1; + uint16_t res1: 4; + uint16_t dOff: 4; + ) + }; + }; +} BlogTcpOffFlags_t; + +typedef struct BlogTcpHdr { + union { + uint8_t u8[BLOG_TCP_HDR_LEN]; + uint16_t u16[BLOG_TCP_HDR_LEN/sizeof(uint16_t)]; + uint32_t u32[BLOG_TCP_HDR_LEN/sizeof(uint32_t)]; + struct { + uint16_t sPort; uint16_t dPort; + uint32_t seq; + uint32_t ackSeq; + BlogTcpOffFlags_t offFlags; uint16_t window; + uint16_t chkSum; uint16_t urgPtr; + }; + }; +} BlogTcpHdr_t; + + +/*----- User Datagram Protocol: RFC 768 definitions --------------------------*/ +#define BLOG_UDP_HDR_LEN 8 + +typedef struct BlogUdpHdr { + union { + uint8_t u8[BLOG_UDP_HDR_LEN]; + uint16_t u16[BLOG_UDP_HDR_LEN/sizeof(uint16_t)]; + uint32_t u32[BLOG_UDP_HDR_LEN/sizeof(uint32_t)]; + struct { + uint16_t sPort; uint16_t dPort; + uint16_t len; uint16_t chkSum; + }; + }; +} BlogUdpHdr_t; + + +/*----- L2TP: RFC 2661 definitions -------------------------------------------*/ +#define BLOG_L2TP_HDR_LEN 8 + +typedef struct BlogL2tpIeFlagsVer { + union { + uint16_t u16; + struct { + BE_DECL( + uint16_t type : 1; + uint16_t lenIe : 1; + uint16_t rsvd2 : 2; + uint16_t seqIe : 1; + uint16_t rsvd1 : 1; + uint16_t offIe : 1; + uint16_t prio : 1; + uint16_t rsvd4 : 4; + uint16_t ver : 4; + ) + LE_DECL( + uint16_t ver : 4; + uint16_t rsvd4 : 4; + uint16_t prio : 1; + uint16_t offIe : 1; + uint16_t rsvd1 : 1; + uint16_t seqIe : 1; + uint16_t rsvd2 : 2; + uint16_t lenIe : 1; + uint16_t type : 1; + ) + }; + }; +} BlogL2tpIeFlagsVer_t; + +typedef struct BlogL2tpHdr { + union { + uint8_t u8[BLOG_L2TP_HDR_LEN]; + uint16_t u16[BLOG_L2TP_HDR_LEN/sizeof(uint16_t)]; + uint32_t u32[BLOG_L2TP_HDR_LEN/sizeof(uint32_t)]; + struct { + BlogL2tpIeFlagsVer_t ieFlagsVer; uint16_t len; + uint16_t tId; uint16_t sId; + /* uint16_t ns; uint16_t nr; + uint16_t offSz; uint16_t offPad; */ + }; + }; +} BlogL2tpHdr_t; + + +/*----- Generic Routing Encapsulation: RFC 2637, PPTP session, RFC 2784 ------*/ +#define BLOG_GRE_HDR_LEN 8 + +typedef struct BlogGreIeFlagsVer { + union { + uint16_t u16; + struct { + BE_DECL( + uint16_t csumIe : 1; + uint16_t rtgIe : 1; + uint16_t keyIe : 1; + uint16_t seqIe : 1; + uint16_t srcRtIe: 1; + uint16_t recurIe: 3; + uint16_t ackIe : 1; + uint16_t flags : 4; + uint16_t ver : 3; + ) + LE_DECL( + uint16_t ver : 3; + uint16_t flags : 4; + uint16_t ackIe : 1; + uint16_t recurIe: 3; + uint16_t srcRtIe: 1; + uint16_t seqIe : 1; + uint16_t keyIe : 1; + uint16_t rtgIe : 1; + uint16_t csumIe : 1; + ) + }; + }; +} BlogGreIeFlagsVer_t; + +typedef struct BlogGreHdr { + union { + uint8_t u8[BLOG_GRE_HDR_LEN]; + uint16_t u16[BLOG_GRE_HDR_LEN/sizeof(uint16_t)]; + uint32_t u32[BLOG_GRE_HDR_LEN/sizeof(uint32_t)]; + struct { + BlogGreIeFlagsVer_t ieFlagsVer; uint16_t proto; + /* RFC2784 specifies csum instead of len, for GRE ver = 0 */ + /* RFC2637 specifies len, for GRE ver=1 used with PPTP */ + uint16_t len; uint16_t callId; + /* uint32_t seqNum; present if seqIe = 1 */ + /* uint32_t ackNum; present if ackIe = 1 */ + }; + }; +} BlogGreHdr_t; + +/*----- VXLAN: RFC 7348 definitions --------------------------------------------------*/ +#define BLOG_VXLAN_PORT 4789 +#define BLOG_VXLAN_HDR_LEN 8 +#define BLOG_VXLAN_TUNNEL_MAX_LEN (BLOG_IPV6_HDR_LEN + BLOG_UDP_HDR_LEN + BLOG_VXLAN_HDR_LEN) +#define BLOG_VXLAN_HF_VNI (1UL << 27) +#define BLOG_VXLAN_VNI_OFFSET 8 +typedef struct BlogVxlanHdr { + union { + uint8_t u8[BLOG_VXLAN_HDR_LEN]; + uint16_t u16[BLOG_VXLAN_HDR_LEN/sizeof(uint16_t)]; + uint32_t u32[BLOG_VXLAN_HDR_LEN/sizeof(uint32_t)]; + struct { + uint32_t flags; + uint32_t vni; + }; + }; +} BlogVxlanHdr_t; + +/* + *------------------------------------------------------------------------------ + * Assert that headers are properly packed (without using attribute packed) + * + * #include <stdio.h> + * #include <stdint.h> + * #include "blog_net.h" + * int main() { + * printf("blog_net_audit_hdrs %d\n", blog_net_audit_hdrs() ); + * return blog_net_audit_hdrs(); + * } + *------------------------------------------------------------------------------ + */ +static inline int blog_net_audit_hdrs(void) +{ +#define BLOG_NET_AUDIT(hdrlen,hdrtype) \ + if (hdrlen != sizeof(hdrtype)) \ + return (-1) + + BLOG_NET_AUDIT( BLOG_ETH_ADDR_LEN, BlogEthAddr_t ); + BLOG_NET_AUDIT( BLOG_ETH_HDR_LEN, BlogEthHdr_t ); + BLOG_NET_AUDIT( BLOG_BRCM6_HDR_LEN, BlogBrcm6Hdr_t ); + BLOG_NET_AUDIT( BLOG_BRCM4_HDR_LEN, BlogBrcm4Hdr_t ); + BLOG_NET_AUDIT( BLOG_ETHBRCM6_HDR_LEN, BlogEthBrcm6Hdr_t ); + BLOG_NET_AUDIT( BLOG_ETHBRCM4_HDR_LEN, BlogEthBrcm4Hdr_t ); + BLOG_NET_AUDIT( BLOG_VLAN_HDR_LEN, BlogVlanHdr_t ); + BLOG_NET_AUDIT( BLOG_PPPOE_HDR_LEN, BlogPppoeHdr_t ); + BLOG_NET_AUDIT( BLOG_MPLS_HDR_LEN, BlogMplsHdr_t ); + BLOG_NET_AUDIT( BLOG_IPV4_ADDR_LEN, BlogIpv4Addr_t ); + BLOG_NET_AUDIT( BLOG_IPV4_HDR_LEN, BlogIpv4Hdr_t ); + BLOG_NET_AUDIT( BLOG_IPV6_ADDR_LEN, BlogIpv6Addr_t ); + BLOG_NET_AUDIT( BLOG_IPV6_HDR_LEN, BlogIpv6Hdr_t ); + BLOG_NET_AUDIT( BLOG_TCP_HDR_LEN, BlogTcpHdr_t ); + BLOG_NET_AUDIT( BLOG_UDP_HDR_LEN, BlogUdpHdr_t ); + BLOG_NET_AUDIT( BLOG_L2TP_HDR_LEN, BlogL2tpHdr_t ); + BLOG_NET_AUDIT( BLOG_GRE_HDR_LEN, BlogGreHdr_t ); + BLOG_NET_AUDIT( BLOG_VXLAN_HDR_LEN, BlogVxlanHdr_t); + + return 0; +} + + + + + +/* + *------------------------------------------------------------------------------ + * Network Utilities : 16bit aligned + *------------------------------------------------------------------------------ + */ +#if defined(CONFIG_CPU_LITTLE_ENDIAN) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) +/* + *------------------------------------------------------------------------------ + * Function : blog_read32_align16 + * Description : Read a 32bit value from a 16 byte aligned data stream + *------------------------------------------------------------------------------ + */ +static inline uint32_t blog_read32_align16( uint16_t * from ) +{ + return (uint32_t)( (from[1] << 16) | from[0] ); +} + +/* + *------------------------------------------------------------------------------ + * Function : blog_write32_align16 + * Description : Write a 32bit value to a 16bit aligned data stream + *------------------------------------------------------------------------------ + */ +static inline void blog_write32_align16( uint16_t * to, uint32_t from ) +{ + to[1] = (uint16_t)htons(from >> 16); + to[0] = (uint16_t)htons(from >> 0); +} + +#elif defined(CONFIG_CPU_BIG_ENDIAN) + +/* + *------------------------------------------------------------------------------ + * Function : blog_read32_align16 + * Description : Read a 32bit value from a 16 byte aligned data stream + *------------------------------------------------------------------------------ + */ +static inline uint32_t blog_read32_align16( uint16_t * from ) +{ + return (uint32_t)( (from[0] << 16) | (from[1]) ); +} + +/* + *------------------------------------------------------------------------------ + * Function : blog_write32_align16 + * Description : Write a 32bit value to a 16bit aligned data stream + *------------------------------------------------------------------------------ + */ +static inline void blog_write32_align16( uint16_t * to, uint32_t from ) +{ + to[0] = (uint16_t)(from >> 16); + to[1] = (uint16_t)(from >> 0); +} +#endif /* defined(CONFIG_CPU_BIG_ENDIAN) */ + +#endif /* defined(__BLOG_NET_H_INCLUDED__) */ diff --git a/include/linux/blog_rule.h b/include/linux/blog_rule.h new file mode 100644 index 0000000000000000000000000000000000000000..c4c099831c344f01632076af45cc651d8e36062e --- /dev/null +++ b/include/linux/blog_rule.h @@ -0,0 +1,256 @@ +#if defined(CONFIG_BLOG) +#ifndef __BLOG_RULE_H_INCLUDED__ +#define __BLOG_RULE_H_INCLUDED__ + +/* +* <:copyright-BRCM:2010:DUAL/GPL:standard +* +* Copyright (c) 2010 Broadcom +* All Rights Reserved +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed +* to you under the terms of the GNU General Public License version 2 +* (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +* with the following added to such license: +* +* As a special exception, the copyright holders of this software give +* you permission to link this software with independent modules, and +* to copy and distribute the resulting executable under terms of your +* choice, provided that you also meet, for each linked independent +* module, the terms and conditions of the license of that module. +* An independent module is a module which is not derived from this +* software. The special exception does not apply to any modifications +* of the software. +* +* Not withstanding the above, under no circumstances may you combine +* this software in any way with any other Broadcom software provided +* under a license other than the GPL, without Broadcom's express prior +* written consent. +* +:> +*/ + +/* + ******************************************************************************* + * + * File Name : blog_rule.h + * + * Description: Blog rules are extensions to a Blog structure that can be used + * to specify additional fiters and modifications. + * + ******************************************************************************* + */ + +#define CC_CONFIG_BLOG_RULE_DEBUG + +#define BLOG_RULE_VERSION "v1.0" + +#define BLOG_RULE_VLAN_TAG_MAX 3 + +#define BLOG_RULE_ACTION_MAX 16 + +#define BLOG_RULE_PBITS_MASK 0xE000 +#define BLOG_RULE_PBITS_SHIFT 13 +#define BLOG_RULE_DEI_MASK 0x1000 +#define BLOG_RULE_DEI_SHIFT 12 +#define BLOG_RULE_VID_MASK 0x0FFF +#define BLOG_RULE_VID_SHIFT 0 + +#define BLOG_RULE_GET_TCI_PBITS(_tci) \ + ( ((_tci) & BLOG_RULE_PBITS_MASK) >> BLOG_RULE_PBITS_SHIFT ) + +#define BLOG_RULE_GET_TCI_DEI(_tci) \ + ( ((_tci) & BLOG_RULE_DEI_MASK) >> BLOG_RULE_DEI_SHIFT ) + +#define BLOG_RULE_GET_TCI_VID(_tci) \ + ( (_tci) & BLOG_RULE_VID_MASK ) + +#define BLOG_RULE_DSCP_IN_TOS_MASK 0xFC +#define BLOG_RULE_DSCP_IN_TOS_SHIFT 2 + +#define BLOG_RULE_IP_PROTO_MASK 0xFF +#define BLOG_RULE_IP_PROTO_SHIFT 0 +#define BLOG_RULE_IP6_NXT_HDR_MASK 0xFF +#define BLOG_RULE_IP6_NXT_HDR_SHIFT 0 + +#define blog_rule_filterInUse(_filter) \ + ({ \ + char *_filter_p = (char *)(&_filter); \ + int _i, _val; \ + for(_i=0; _i<sizeof(_filter); ++_i) { \ + if((_val = _filter_p[_i]) != 0) break; \ + } \ + _val; \ + }) + +typedef struct { + struct ethhdr mask; + struct ethhdr value; +} blogRuleFilterEth_t; + +typedef struct { + union { + struct vlan_hdr mask; + uint32_t mask32; + }; + union { + struct vlan_hdr value; + uint32_t value32; + }; +} blogRuleFilterVlan_t; + +typedef struct { + /* only contains the fields we are interested */ + uint8_t tos; + uint8_t ip_proto; +} blogRuleIpv4Header_t; + +typedef struct { + blogRuleIpv4Header_t mask; + blogRuleIpv4Header_t value; +} blogRuleFilterIpv4_t; + +typedef struct { + /* only contains the fields we are interested */ + uint8_t tclass; + uint8_t nxtHdr; +} blogRuleIpv6Header_t; + +typedef struct { + blogRuleIpv6Header_t mask; + blogRuleIpv6Header_t value; +} blogRuleFilterIpv6_t; + +typedef struct { + uint32_t priority; /* skb priority filter value is offset by 1 because + * 0 is reserved to indicate filter not in use. + * Therefore the supported skb priority range is + * [0 to 0xfffffffe]. + */ + uint16_t markFlowId; + uint16_t markPort; /* port mark filter value is offset by 1 because + * 0 is reserved to indicate filter not in use. + * Therefore use 16-bit to cover the supported + * port range [0 to 255]. + */ +} blogRuleFilterSkb_t; + +typedef struct { + blogRuleFilterEth_t eth; + uint32_t nbrOfVlanTags; + blogRuleFilterVlan_t vlan[BLOG_RULE_VLAN_TAG_MAX]; + uint32_t hasPppoeHeader; + blogRuleFilterIpv4_t ipv4; + blogRuleFilterIpv6_t ipv6; + blogRuleFilterSkb_t skb; + uint32_t flags; +#define BLOG_RULE_FILTER_FLAGS_IS_UNICAST 0x0001 +#define BLOG_RULE_FILTER_FLAGS_IS_MULTICAST 0x0002 +#define BLOG_RULE_FILTER_FLAGS_IS_BROADCAST 0x0004 +} blogRuleFilter_t; + +#define BLOG_RULE_FILTER_FLAGS_ALL \ + ( BLOG_RULE_FILTER_FLAGS_IS_UNICAST | \ + BLOG_RULE_FILTER_FLAGS_IS_MULTICAST | \ + BLOG_RULE_FILTER_FLAGS_IS_BROADCAST ) + +#undef BLOG_RULE_DECL +#define BLOG_RULE_DECL(x) x + +typedef enum { + BLOG_RULE_DECL(BLOG_RULE_CMD_NOP=0), + BLOG_RULE_DECL(BLOG_RULE_CMD_SET_MAC_DA), + BLOG_RULE_DECL(BLOG_RULE_CMD_SET_MAC_SA), + BLOG_RULE_DECL(BLOG_RULE_CMD_SET_ETHERTYPE), + BLOG_RULE_DECL(BLOG_RULE_CMD_PUSH_VLAN_HDR), + BLOG_RULE_DECL(BLOG_RULE_CMD_POP_VLAN_HDR), + BLOG_RULE_DECL(BLOG_RULE_CMD_SET_PBITS), + BLOG_RULE_DECL(BLOG_RULE_CMD_SET_DEI), + BLOG_RULE_DECL(BLOG_RULE_CMD_SET_VID), + BLOG_RULE_DECL(BLOG_RULE_CMD_SET_VLAN_PROTO), + BLOG_RULE_DECL(BLOG_RULE_CMD_COPY_PBITS), + BLOG_RULE_DECL(BLOG_RULE_CMD_COPY_DEI), + BLOG_RULE_DECL(BLOG_RULE_CMD_COPY_VID), + BLOG_RULE_DECL(BLOG_RULE_CMD_COPY_VLAN_PROTO), +// BLOG_RULE_DECL(BLOG_RULE_CMD_XLATE_DSCP_TO_PBITS), + BLOG_RULE_DECL(BLOG_RULE_CMD_POP_PPPOE_HDR), + BLOG_RULE_DECL(BLOG_RULE_CMD_SET_DSCP), + BLOG_RULE_DECL(BLOG_RULE_CMD_DECR_TTL), + BLOG_RULE_DECL(BLOG_RULE_CMD_DECR_HOP_LIMIT), + BLOG_RULE_DECL(BLOG_RULE_CMD_DROP), + BLOG_RULE_DECL(BLOG_RULE_CMD_SET_SKB_MARK_PORT), + BLOG_RULE_DECL(BLOG_RULE_CMD_SET_SKB_MARK_QUEUE), + BLOG_RULE_DECL(BLOG_RULE_CMD_OVRD_LEARNING_VID), + BLOG_RULE_DECL(BLOG_RULE_CMD_SET_STA_MAC_ADDRESS), + BLOG_RULE_DECL(BLOG_RULE_CMD_MAX) +} blogRuleCommand_t; + +typedef struct { + uint8_t cmd; // blogRuleCommand_t + uint8_t toTag; + union { + uint16_t etherType; + uint16_t tpid; + uint16_t pbits; + uint16_t dei; + uint16_t vid; + uint16_t vlanProto; + uint16_t dscp; + uint16_t fromTag; + uint16_t skbMarkQueue; + uint16_t skbMarkPort; + uint16_t arg; + uint8_t macAddr[ETH_ALEN]; + }; +} blogRuleAction_t; + +typedef struct blogRule { + blogRuleFilter_t filter; + uint32_t actionCount; + blogRuleAction_t action[BLOG_RULE_ACTION_MAX]; + struct blogRule *next_p; +} blogRule_t; + +typedef enum { + BLOG_RULE_VLAN_NOTIFY_DIR_RX, + BLOG_RULE_VLAN_NOTIFY_DIR_TX, + BLOG_RULE_VLAN_NOTIFY_DIR_MAX +} blogRuleVlanNotifyDirection_t; + +/* + * blogRuleVlanHook_t: The Linux VLAN manager must use this hook to register + * the handler that creates Blog Rules based on the configured VLAN Rules. + */ +typedef int (* blogRuleVlanHook_t)(void *arg_p, + struct net_device *rxVlanDev, + struct net_device *txVlanDev); + +/* + * blogRuleVlanNotifyHook_t: The Linux VLAN manager uses this hook to notify + * the registered handler whenever VLAN Rules are added or removed. + * The device (dev) can be either a VLAN interface or a Real interface. + */ +typedef void (* blogRuleVlanNotifyHook_t)(struct net_device *dev, + blogRuleVlanNotifyDirection_t direction, + uint32_t nbrOfTags); + +extern blogRuleVlanHook_t blogRuleVlanHook; +extern blogRuleVlanNotifyHook_t blogRuleVlanNotifyHook; + +typedef int (* blogArlHook_t)(void *e); + +extern blogArlHook_t bcm_arl_process_hook_g; + +/* -------------- User API -------------- */ + +blogRule_t *blog_rule_alloc(void); +void blog_rule_free(blogRule_t *blogRule_p); +int blog_rule_free_list(void *blogRule_p); +void blog_rule_init(blogRule_t *blogRule_p); +void blog_rule_dump(blogRule_t *blogRule_p); +int blog_rule_add_action(blogRule_t *blogRule_p, blogRuleAction_t *action_p); +int blog_rule_delete_action(void *rule_p); + +#endif /* defined(__BLOG_RULE_H_INCLUDED__) */ +#endif /* defined(CONFIG_BLOG) */ diff --git a/include/linux/br_fp.h b/include/linux/br_fp.h new file mode 100644 index 0000000000000000000000000000000000000000..4b0a4c4d3030b661eba1a469d64b67334c24db0a --- /dev/null +++ b/include/linux/br_fp.h @@ -0,0 +1,73 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef BR_FP_H +#define BR_FP_H + +#include <linux/device.h> +#include <linux/module.h> + +#define BR_FP_FDB_ADD 1 +#define BR_FP_FDB_REMOVE 2 +#define BR_FP_FDB_MODIFY 3 +#define BR_FP_FDB_CHECK_AGE 4 +#define BR_FP_PORT_ADD 5 +#define BR_FP_PORT_REMOVE 6 +#define BR_FP_LOCAL_SWITCHING_DISABLE 7 +#define BR_FP_BRIDGE_TYPE 8 + +#if defined(CONFIG_BCM_RDPA_BRIDGE) || defined(CONFIG_BCM_RDPA_BRIDGE_MODULE) +struct br_fp_data +{ + int (*rdpa_hook)(int cmd, void *in, void *out); + void *rdpa_obj; +}; +#endif /* CONFIG_BCM_RDPA_BRIDGE || CONFIG_BCM_RDPA_BRIDGE_MODULE */ + +struct bcm_br_ext +{ +#if defined(CONFIG_BCM_RDPA_BRIDGE) || defined(CONFIG_BCM_RDPA_BRIDGE_MODULE) + struct br_fp_data br_fp_data; +#define bridge_fp_data_hook_get(_br_dev) (bcm_netdev_ext_field_get((_br_dev), bcm_br_ext.br_fp_data.rdpa_hook)) +#define bridge_fp_data_hook_set(_br_dev, _hook) bcm_netdev_ext_field_set((_br_dev), bcm_br_ext.br_fp_data.rdpa_hook, (_hook)) +#define bridge_fp_data_obj_get(_br_dev) (bcm_netdev_ext_field_get((_br_dev), bcm_br_ext.br_fp_data.rdpa_obj)) +#define bridge_fp_data_obj_set(_br_dev, _obj) bcm_netdev_ext_field_set((_br_dev), bcm_br_ext.br_fp_data.rdpa_obj, (_obj)) + +#define br_fp_hook(_br_dev, _cmd, _arg1, _arg2) (bridge_fp_data_hook_get((_br_dev)) ? bridge_fp_data_hook_get((_br_dev))((_cmd), (_arg1), (_arg2)) : 0) +#endif + +#if defined(CONFIG_BCM_RDPA_BRIDGE) || defined(CONFIG_BCM_RDPA_BRIDGE_MODULE) + int local_switching_disable; +#define bridge_local_switching_disable_get(_br_dev) (bcm_netdev_ext_field_get((_br_dev), bcm_br_ext.local_switching_disable)) +#define bridge_local_switching_disable_set(_br_dev, _val) bcm_netdev_ext_field_set((_br_dev), bcm_br_ext.local_switching_disable, (_val)) +#else +#define bridge_local_switching_disable_get(_br_dev) ((void)(_br_dev), 0) +#define bridge_local_switching_disable_set(_br_dev, _val) ((void)(_br_dev), (void)(_val), 0) +#endif + +#if defined(CONFIG_BCM_RDPA_BRIDGE) || defined(CONFIG_BCM_RDPA_BRIDGE_MODULE) + u32 mac_entry_discard_counter; +#define bridge_mac_entry_discard_counter_get(_br_dev) (bcm_netdev_ext_field_get((_br_dev), bcm_br_ext.mac_entry_discard_counter)) +#define bridge_mac_entry_discard_counter_set(_br_dev, _val) bcm_netdev_ext_field_set((_br_dev), bcm_br_ext.mac_entry_discard_counter, (_val)) +#define bridge_mac_entry_discard_counter_inc(_br_dev) ((bcm_netdev_ext_field_get((_br_dev), bcm_br_ext.mac_entry_discard_counter)++)) +#else +#define bridge_mac_entry_discard_counter_get(_br_dev) ((void)(br_dev), 0) +#define bridge_mac_entry_discard_counter_set(_br_dev, _val) do {} while(0) +#define bridge_mac_entry_discard_counter_inc(_br_dev) do {} while(0) +#endif +}; + +#endif /* BR_FP_H */ diff --git a/include/linux/brcm_dll.h b/include/linux/brcm_dll.h new file mode 100644 index 0000000000000000000000000000000000000000..3358c2de7d252635b585744f795016f377d68bc0 --- /dev/null +++ b/include/linux/brcm_dll.h @@ -0,0 +1,123 @@ +#ifndef _dll_t_ +#define _dll_t_ +/* +<:copyright-BRCM:2014:DUAL/GPL:standard + + Copyright (c) 2014 Broadcom + All Rights Reserved + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + +#if !defined(_envelope_of) +/* derived from container_of, without "const", for gcc -Wcast-qual compile */ +#define _envelope_of(ptr, type, member) \ +({ \ + typeof(((type *)0)->member) *__mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type, member)); \ +}) +#endif /* _envelope_of */ + + +typedef struct dll_t dll_t; /* common to wlan bcmutils.h, pktHdr.h */ +typedef struct dll_t { + dll_t * next_p; + dll_t * prev_p; +} Dll_t, * PDll_t; + +#define dll dll_t + +#define DLL_STRUCT_INITIALIZER(struct_name, dll_name) \ + { .next_p = &(struct_name).dll_name, .prev_p = &(struct_name).dll_name } + +#define dll_init(node_p) ((node_p)->next_p = (node_p)->prev_p = (node_p)) + +/* dll macros returing a "dll_t *" */ +#define dll_head_p(list_p) ((list_p)->next_p) +#define dll_tail_p(list_p) ((list_p)->prev_p) + +#define dll_next_p(node_p) ((node_p)->next_p) +#define dll_prev_p(node_p) ((node_p)->prev_p) + +#define dll_empty(list_p) ((list_p)->next_p == (list_p)) +#define dll_end(list_p, node_p) ((list_p) == (node_p)) + +/* inserts the node new_p "after" the node at_p */ +#define dll_insert(new_p, at_p) \ +({ \ + (new_p)->next_p = (at_p)->next_p; \ + (new_p)->prev_p = (at_p); \ + (at_p)->next_p = (new_p); \ + (new_p)->next_p->prev_p = (new_p); \ +}) + +#define dll_append(list_p, node_p) dll_insert((node_p), dll_tail_p(list_p)) +#define dll_prepend(list_p, node_p) dll_insert((node_p), (list_p)) + +/* deletes a node from any list that it "may" be in, if at all. */ +#define dll_delete(node_p) \ +({ \ + (node_p)->prev_p->next_p = (node_p)->next_p; \ + (node_p)->next_p->prev_p = (node_p)->prev_p; \ +}) + +/** + * dll_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + * + * Iterator "pos" may not be moved. + * + * If you need to delete the iterator, then use the below sample. + * dll_t * iter_p, * next_p; + * for (iter_p = dll_head_p(&someList); ! dll_end(&someList, iter_p); + * iter_p = next_p) + * { + * next_p = dll_next_p(iter_p); + * ... use iter_p at will, including removing it from list ... + * } + * + */ +#define dll_for_each(pos, head) \ + for (pos = (head)->next_p; pos != (head); pos = pos->next_p) + +/** + * Take all elements of list A and join them to the tail of list B. + * List A must not be empty and list A will be returned as an empty list. + */ +#define dll_join(listA_p, listB_p) \ +({ \ + dll_t *_listB_p = (listB_p); \ + dll_t *headA_p = dll_head_p(listA_p); \ + dll_t *tailA_p = dll_tail_p(listA_p); \ + dll_t *tailB_p = dll_tail_p(listB_p); \ + /* Link up list B's tail to list A's head */ \ + headA_p->prev_p = tailB_p; \ + tailB_p->next_p = headA_p; \ + /* Make list A's tail to be list B's new tail */ \ + tailA_p->next_p = (listB_p); \ + _listB_p->prev_p = tailA_p; \ + dll_init(listA_p); \ +}) + +#endif /* ! defined(_dll_t_) */ diff --git a/include/linux/buzzz_kevt.h b/include/linux/buzzz_kevt.h new file mode 100644 index 0000000000000000000000000000000000000000..1530b1655d0a77870cfde9a3557c7690fe78b62c --- /dev/null +++ b/include/linux/buzzz_kevt.h @@ -0,0 +1,81 @@ +#ifndef __buzzz_kevt_h_included__ +#define __buzzz_kevt_h_included__ + +#if defined(CONFIG_BUZZZ_KEVT) || defined(CONFIG_BUZZZ_FUNC) +/* + * +---------------------------------------------------------------------------- + * + * BCM BUZZZ ARM Cortex A9 Router Kernel events + * + * $Copyright Open Broadcom Corporation$ + * $Id$ + * + * vim: set ts=4 noet sw=4 tw=80: + * -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- + * + * +---------------------------------------------------------------------------- + */ + +#include <uapi/linux/buzzz.h> + +#undef BUZZZ_KEVT +#define BUZZZ_KEVT(event) BUZZZ_KEVT__ ## event, + +#define BUZZZ_KEVT_REG(event, format) \ + buzzz_event_reg(BUZZZ_KEVT__## event, "\t\t" format); + +/** + * DO NOT SUBMIT USER EVENTS + * + * For private debug (not for submission), a user event may be added by: + * 1. Add an enum entry to buzzz_rtr_dpid, + * e.g. BUZZZ_KEVT(HELLO_WORLD) + * + * 2. Add an entry to buzzz_dp_init(), + * e.g. BUZZZ_KEVT_REG(HELLO_WORLD, "hello world at %pS from %pS") + * + * 3. In source code base, insert instrumentation: + * e.g. BUZZZ_DPL3(HELLO_WORLD, 2, + * BUZZZ32(BUZZZ_CUR_IP_), BUZZZ32(BUZZZ_RET_IP_)); + * + * See uapi/linux/buzzz.h, where BUZZZ_DPL tracing level is set to 3, thereby + * enabling all instrumentations BUZZZ_DPL1(), BUZZZ_DPL2() and BUZZZ_DPL3() + * Instrumentation with BUZZZ_DPL4() and BUZZZ_DPL5() are compiled out. + * + * Second parameter to BUZZZ_DPL#() specifies the number of arguments to be + * logged, in the above example, it is 2 arguments (maximum 3 arguments). + * - First argument in example is current instruction address, and + * - Second argument is return address. + * Arguments are 32bit values. [Gets messy on 64b aarch] + * + * Do not forget to invoke, buzzz_dp_init() once ... say in a module init. + */ +typedef +enum buzzz_rtr_dpid +{ + BUZZZ_KEVT__DATAPATH_START = 100, + + BUZZZ_KEVT(SAMPLE) + /* Define user events here */ + +} buzzz_rtr_dpid_t; + + +/* Invoke this once in a datapath module's init */ +static inline int +buzzz_dp_init(void) +{ + BUZZZ_KEVT_REG(SAMPLE, "sample pkt<%p>") + /* Add user event logs here */ + + return 0; +} +#else /* ! CONFIG_BUZZZ */ +#define BUZZZ_DPL1(ID, N, ARG...) do {} while (0) +#define BUZZZ_DPL2(ID, N, ARG...) do {} while (0) +#define BUZZZ_DPL3(ID, N, ARG...) do {} while (0) +#define BUZZZ_DPL4(ID, N, ARG...) do {} while (0) +#define BUZZZ_DPL5(ID, N, ARG...) do {} while (0) +#endif /* ! CONFIG_BUZZZ */ + +#endif /* __buzzz_kevt_h_included__ */ diff --git a/include/linux/dpi.h b/include/linux/dpi.h new file mode 100644 index 0000000000000000000000000000000000000000..2213408ea66cbfc4b27d8c866da3b421a7a028bc --- /dev/null +++ b/include/linux/dpi.h @@ -0,0 +1,116 @@ +#if defined(CONFIG_BCM_KF_DPI) +#ifndef _LINUX_DPI_H +#define _LINUX_DPI_H + +#include <linux/if_ether.h> +#include <linux/list.h> + +#define DPI_APPID_ONGOING_BIT 0 +#define DPI_APPID_IDENTIFIED_BIT 1 +#define DPI_APPID_FINAL_BIT 2 +#define DPI_APPID_STOP_CLASSIFY_BIT 3 +#define DPI_APPID_RESYNC_BIT 4 +#define DPI_DEVID_ONGOING_BIT 5 +#define DPI_DEVID_IDENTIFIED_BIT 6 +#define DPI_DEVID_FINAL_BIT 7 +#define DPI_DEVID_STOP_CLASSIFY_BIT 8 +#define DPI_URL_STOP_CLASSIFY_BIT 9 +#define DPI_CLASSIFICATION_STOP_BIT 14 +#define DPI_CT_INIT_FROM_WAN_BIT 15 +#define DPI_CT_DS_BYPASS_BIT 29 +#define DPI_CT_US_BYPASS_BIT 30 +#define DPI_CT_BLOCK_BIT 31 + +#define DPI_NL_CHANGE_MASK (1 << DPI_CT_BLOCK_BIT) + +#define DPI_URLINFO_MAX_HOST_LEN 64 +/* 256 was chosen as the max length of a hostname in a DHCP packet is 255. */ +#define DPI_HOSTNAME_MAX_LEN 256 + +#define dpi_ct_init_from_wan(ct) \ + test_bit(DPI_CT_INIT_FROM_WAN_BIT, &(ct)->bcm_ext.dpi.flags) + +struct dpi_ct_stats { + u64 pkts; + u64 bytes; +}; + +struct dpi_app { + u32 app_id; + atomic_t refcount; + struct hlist_node node; +}; + +struct dpi_dev { + u8 mac[ETH_ALEN]; + + u32 dev_id; + u16 category; + u16 family; + u16 vendor; + u16 os; + u16 os_class; + u16 prio; + char hostname[DPI_HOSTNAME_MAX_LEN]; + + struct dpi_ct_stats us; + struct dpi_ct_stats ds; + + atomic_t refcount; + struct hlist_node node; +}; + +struct dpi_appinst { + struct dpi_app *app; + struct dpi_dev *dev; + struct dpi_ct_stats us; + struct dpi_ct_stats ds; + atomic_t refcount; + struct hlist_node node; +}; + +struct dpi_url { + u32 len; + char hostname[DPI_URLINFO_MAX_HOST_LEN]; + atomic_t refcount; + struct hlist_node node; +}; + +struct dpi_info { + struct dpi_dev *dev; + struct dpi_app *app; + struct dpi_appinst *appinst; + struct dpi_url *url; + unsigned long flags; +}; + +struct nf_conn; + +struct dpi_core_hooks { + void (*delete)(struct nf_conn *ct); +}; + +struct dpi_ct_hooks { + int (*event_report)(int eventmask, struct nf_conn *ct, u32 portid, + int report); +}; + +/* ----- dpi functions ----- */ +struct dpi_info *dpi_info_get(struct nf_conn *conn); +u32 dpi_app_id(struct dpi_app *app); +u32 dpi_dev_id(struct dpi_dev *dev); +u8 *dpi_mac(struct dpi_dev *dev); +int dpi_url_len(struct dpi_url *url); +char *dpi_url(struct dpi_url *url); +struct dpi_ct_stats *dpi_appinst_stats(struct nf_conn *ct, int dir); +struct dpi_ct_stats *dpi_dev_stats(struct nf_conn *ct, int dir); +void dpi_block(struct nf_conn *conn); +void dpi_nf_ct_delete(struct nf_conn *ct); +int dpi_core_hooks_register(struct dpi_core_hooks *h); +void dpi_core_hooks_unregister(void); +int dpi_nf_ct_event_report(struct nf_conn *ct, u32 portid); +void dpi_conntrack_init(void); +void dpi_conntrack_cleanup(void); + +#endif /* _LINUX_DPI_H */ +#endif /* defined(CONFIG_BCM_KF_DPI) */ diff --git a/include/linux/gbpm.h b/include/linux/gbpm.h new file mode 100644 index 0000000000000000000000000000000000000000..9fbaf90bbec6c633703eeed747be880c1f977e2e --- /dev/null +++ b/include/linux/gbpm.h @@ -0,0 +1,344 @@ +#ifndef __GBPM_H_INCLUDED__ +#define __GBPM_H_INCLUDED__ + +/* + * +<:copyright-BRCM:2007:DUAL/GPL:standard + + Copyright (c) 2007 Broadcom + All Rights Reserved + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + +/* + ******************************************************************************* + * File Name : gbpm.h + * + ******************************************************************************* + */ +#define GBPM_VERSION "v0.1" +#define GBPM_VER_STR GBPM_VERSION +#define GBPM_MODNAME "Broadcom GBPM " + +#define GBPM_ERROR (-1) +#define GBPM_SUCCESS 0 + +#define GBPM_RXCHNL_MAX 4 +#define GBPM_RXCHNL_DISABLED 0 +#define GBPM_RXCHNL_ENABLED 1 + +#define CONFIG_GBPM_API_HAS_GET_TOTAL_BUFS 1 +#define CONFIG_GBPM_API_HAS_GET_AVAIL_BUFS 1 + + +#if defined(CONFIG_BCM_XTMCFG) || defined(CONFIG_BCM_XTMCFG_MODULE) +#define GBPM_XTM_SUPPORT +#endif + +typedef enum { + GBPM_PORT_ETH, + GBPM_PORT_XTM, + GBPM_PORT_FWD, + GBPM_PORT_WLAN, + GBPM_PORT_USB, + GBPM_PORT_MAX +} gbpm_port_t; + +#if defined(CONFIG_BCM_BPM_BUF_TRACKING) +typedef enum { + GBPM_REF_BUFF, + GBPM_REF_FKB, + GBPM_REF_SKB +} gbpm_reftype_t; + +typedef enum { + GBPM_DRV_BPM, + GBPM_DRV_ETH, + GBPM_DRV_XTM, + GBPM_DRV_KERN, + GBPM_DRV_BDMF, + GBPM_DRV_ARCHER, + GBPM_DRV_MAX +} gbpm_driver_t; + +typedef enum { + GBPM_VAL_UNMARKED, + GBPM_VAL_ALLOC, + GBPM_VAL_CLONE, + GBPM_VAL_RECYCLE, + GBPM_VAL_FREE, + GBPM_VAL_RX, + GBPM_VAL_TX, + GBPM_VAL_ENTER, + GBPM_VAL_EXIT, + GBPM_VAL_INFO, + GBPM_VAL_INIT, + GBPM_VAL_COPY_SRC, + GBPM_VAL_COPY_DST, + GBPM_VAL_XLATE, + GBPM_VAL_MAX +} gbpm_value_t; + +typedef struct +{ + size_t addr; + union { + uint16_t word; + struct { + uint16_t driver:4; + uint16_t info:4; + uint16_t reftype:2; + uint16_t value:6; + }; + }; +} gbpm_mark_t; + +typedef struct +{ + atomic_t ref_cnt; + atomic_t idle_cnt; + uint32_t write; + gbpm_mark_t * mbuf_p; +} gbpm_trail_t; + +typedef void (* gbpm_mark_buf_hook_t) ( void *, void *, int, int, int, int ); +typedef void (* gbpm_add_ref_hook_t) ( void *, int ); +#endif /* bpm tracking */ + +/* + *----------------------------------------------------------------------------- + * GBPM callbacks are managed in a single global instantiation of gbpm_t gbpm_g + * GBPM Hooks may be viewed as "BPM" callbacks and "User" callbacks. + * - GBPM_BIND() lists all BPM callbacks + * - GBPM_USER() lists all USER callbacks (bind per user driver module). + *----------------------------------------------------------------------------- + */ + +/* GBPM_DECL may be undef/define, for GBPM_BIND and GBPM_USER template usage */ +#define GBPM_BIND() \ + /* --- BPM BUF POOL --- */ \ + GBPM_DECL(alloc_mult_buf) \ + GBPM_DECL(alloc_mult_buf_ex) \ + GBPM_DECL(free_mult_buf) \ + GBPM_DECL(alloc_buf) \ + GBPM_DECL(free_buf) \ + /* --- BPM SKB POOL --- */ \ + GBPM_DECL(total_skb) \ + GBPM_DECL(avail_skb) \ + GBPM_DECL(attach_skb) \ + GBPM_DECL(alloc_skb) \ + GBPM_DECL(alloc_buf_skb_attach) \ + GBPM_DECL(alloc_mult_skb) \ + GBPM_DECL(free_skb) \ + GBPM_DECL(free_skblist) \ + GBPM_DECL(invalidate_dirtyp) \ + GBPM_DECL(recycle_skb) \ + /* --- BPM pNBuff --- */ \ + GBPM_DECL(recycle_pNBuff) \ + /* --- BPM Get Accessors --- */ \ + GBPM_DECL(get_dyn_buf_lvl) \ + GBPM_DECL(get_total_bufs) \ + GBPM_DECL(get_avail_bufs) \ + GBPM_DECL(get_max_dyn_bufs) \ + /* --- BPM Runtime --- */ \ + GBPM_DECL(resv_rx_buf) \ + GBPM_DECL(unresv_rx_buf) + + + /* --- BPM Users --- */ +#define GBPM_ENET() \ + GBPM_DECL(enet_status) +#if defined(GBPM_XTM_SUPPORT) +#define GBPM_XTM() \ + GBPM_DECL(xtm_status) \ + GBPM_DECL(xtm_thresh) +#else +#define GBPM_XTM() +#endif /* GBPM_XTM_SUPPORT */ + +#define GBPM_USER() \ + GBPM_ENET() \ + GBPM_XTM() + +/* + * typedefs for callbacks managed by GBPM. + */ + +/* --- BPM BUF POOL --- */ +typedef int (* gbpm_alloc_mult_buf_hook_t)(uint32_t, void **); +typedef void (* gbpm_free_mult_buf_hook_t)( uint32_t, void **); +typedef int (* gbpm_alloc_mult_buf_ex_hook_t)( uint32_t num, void **buf_p, uint32_t prio ); +typedef void * (* gbpm_alloc_buf_hook_t)(void); +typedef void (* gbpm_free_buf_hook_t)(void *); +typedef void (* gbpm_recycle_pNBuff_hook_t)(void *, unsigned long, uint32_t); + +/* --- BPM SKB POOL --- */ +typedef uint32_t (* gbpm_total_skb_hook_t)(void); +typedef uint32_t (* gbpm_avail_skb_hook_t)(void); +typedef void (* gbpm_attach_skb_hook_t)(void *, void *, uint32_t); +typedef void * (* gbpm_alloc_skb_hook_t)(void); +typedef void * (* gbpm_alloc_buf_skb_attach_hook_t)(uint32_t); +typedef void * (* gbpm_alloc_mult_skb_hook_t)(uint32_t); +typedef void (* gbpm_free_skb_hook_t)(void *); +typedef void (* gbpm_free_skblist_hook_t)(void *head, void *tail, uint32_t len, void **bufp_arr); +typedef void * (* gbpm_invalidate_dirtyp_hook_t)(void *); +typedef void (* gbpm_recycle_skb_hook_t)(void *, unsigned long, uint32_t); + +/* --- BPM Get Accessors --- */ +typedef int (* gbpm_get_dyn_buf_lvl_hook_t)(void); +typedef uint32_t (* gbpm_get_total_bufs_hook_t)(void); +typedef uint32_t (* gbpm_get_avail_bufs_hook_t)(void); +typedef uint32_t (* gbpm_get_max_dyn_bufs_hook_t)(void); + +/* --- BPM Set Accessors --- */ +typedef void (* gbpm_upd_buf_lvl_hook_t)(int); + +/* --- BPM Runtime --- */ +typedef int (* gbpm_resv_rx_buf_hook_t)(gbpm_port_t, uint32_t, uint32_t, uint32_t); +typedef int (* gbpm_unresv_rx_buf_hook_t)(gbpm_port_t, uint32_t); + + +/* --- BPM User --- */ +typedef void (* gbpm_evt_hook_t)(void); +typedef void (* gbpm_thresh_hook_t)(void); +typedef void (* gbpm_status_hook_t)(void); + + +/* --- BPM User instantiations --- */ +typedef gbpm_status_hook_t gbpm_enet_status_hook_t; +typedef gbpm_status_hook_t gbpm_fap_status_hook_t; +typedef gbpm_thresh_hook_t gbpm_fap_thresh_hook_t; +typedef gbpm_thresh_hook_t gbpm_enet_thresh_hook_t; +typedef gbpm_thresh_hook_t gbpm_fap_enet_thresh_hook_t; +typedef gbpm_upd_buf_lvl_hook_t gbpm_fap_upd_buf_lvl_hook_t; +/* gbpm_fap_evt_hook_g is instantiated in dev.c and not part of gbpm_g */ +typedef gbpm_evt_hook_t gbpm_fap_evt_hook_t; + +typedef gbpm_status_hook_t gbpm_xtm_status_hook_t; +typedef gbpm_thresh_hook_t gbpm_xtm_thresh_hook_t; + + +/* Typedef of the Global BPM hook manager */ +#undef GBPM_DECL +#define GBPM_DECL(HOOKNAME) gbpm_ ## HOOKNAME ## _hook_t HOOKNAME; + +typedef struct gbpm +{ + GBPM_BIND() /* List of BPM "BIND" hooks */ + GBPM_USER() /* List of DRV "USER" hooks */ + uint32_t debug; +} gbpm_t; + +extern gbpm_t gbpm_g; /* exported global */ + + +/* BPM registering callbacks into GBPM */ +#undef GBPM_DECL +#define GBPM_DECL(HOOKNAME) gbpm_ ## HOOKNAME ## _hook_t HOOKNAME, + +void gbpm_bind( GBPM_BIND() uint32_t debug ); +void gbpm_unbind(void); + +void gbpm_queue_work(void); + +/* + * Wrappers for GBPM callbacks + */ + +/* --- BPM BUF POOL --- */ +static inline int gbpm_alloc_mult_buf(uint32_t num, void **buf_p) + { return gbpm_g.alloc_mult_buf(num, buf_p); } +static inline int gbpm_alloc_mult_buf_ex( uint32_t num, void **buf_p, uint32_t prio ) + { return gbpm_g.alloc_mult_buf_ex(num, buf_p, prio); } +static inline void gbpm_free_mult_buf(uint32_t num, void **buf_p) + { gbpm_g.free_mult_buf(num, buf_p); } +static inline void * gbpm_alloc_buf(void) + { return gbpm_g.alloc_buf(); } +static inline void gbpm_free_buf(void * buf_p) + { return gbpm_g.free_buf(buf_p); } + +/* --- BPM SKB --- */ +static inline uint32_t gbpm_total_skb(void) + { return gbpm_g.total_skb(); } +static inline uint32_t gbpm_avail_skb(void) + { return gbpm_g.avail_skb(); } +static inline void gbpm_attach_skb(void *skbp, void *data, uint32_t datalen) + { gbpm_g.attach_skb(skbp, data, datalen); } +static inline void * gbpm_alloc_skb(void) + { return gbpm_g.alloc_skb(); } +static inline void * gbpm_alloc_buf_skb_attach(uint32_t datalen) + { return gbpm_g.alloc_buf_skb_attach(datalen); } +static inline void * gbpm_alloc_mult_skb(uint32_t num) + { return gbpm_g.alloc_mult_skb(num); } +static inline void gbpm_free_skb(void *skbp) + { gbpm_g.free_skb(skbp); } +static inline void gbpm_free_skblist(void *head, void *tail, uint32_t len, void **bufp_arr) + { gbpm_g.free_skblist(head, tail, len, bufp_arr); } +static inline void * gbpm_invalidate_dirtyp(void *skb) + { return gbpm_g.invalidate_dirtyp(skb); } +static inline void gbpm_recycle_skb(void *skbp, unsigned long context, + uint32_t recycle_action) + { gbpm_g.recycle_skb(skbp, context, recycle_action); } + +/* --- BPM pNBuff --- */ +static inline void gbpm_recycle_pNBuff(void * pNBuff, unsigned long context, + uint32_t recycle_action) + { gbpm_g.recycle_pNBuff(pNBuff, context, recycle_action); } + + +/* --- BPM Get Accessors --- */ +static inline int gbpm_get_dyn_buf_lvl(void) + { return gbpm_g.get_dyn_buf_lvl(); } +static inline uint32_t gbpm_get_total_bufs(void) + { return gbpm_g.get_total_bufs(); } +static inline uint32_t gbpm_get_avail_bufs(void) + { return gbpm_g.get_avail_bufs(); } +static inline uint32_t gbpm_get_max_dyn_bufs(void) + { return gbpm_g.get_max_dyn_bufs(); } + +/* --- BPM Runtime --- */ +static inline int gbpm_resv_rx_buf(gbpm_port_t port, uint32_t chnl, + uint32_t num_rx_buf, uint32_t bulk_alloc_cnt) + { return gbpm_g.resv_rx_buf(port, chnl, num_rx_buf, bulk_alloc_cnt); } +static inline int gbpm_unresv_rx_buf(gbpm_port_t port, uint32_t chnl) + { return gbpm_g.unresv_rx_buf( port, chnl ); } + +#if defined(CONFIG_BCM_BPM_BUF_TRACKING) +void gbpm_mark_buf( void * buf_p, void * addr, int reftype, int driver, int value, int info); +void gbpm_add_ref( void * buf_p, int i ); + +#define GBPM_TRACK_BUF(buf, drv, value, info) do { gbpm_mark_buf( (void *)(buf), (void *)0, GBPM_REF_BUFF, (drv), (value), (info) ); } while(0) +#define GBPM_TRACK_SKB(skb, drv, value, info) do { gbpm_mark_buf( (void *)((skb)->data), (void *)(skb), GBPM_REF_SKB, (drv), (value), (info) ); } while(0) +#define GBPM_TRACK_FKB(fkb, drv, value, info) do { gbpm_mark_buf( (void *)((fkb)->data), (void *)(fkb), GBPM_REF_FKB, (drv), (value), (info) ); } while(0) +#define GBPM_INC_REF(buf) do { gbpm_add_ref( (buf), 1); } while (0) +#define GBPM_DEC_REF(buf) do { gbpm_add_ref( (buf), -1); } while (0) +#else +#define GBPM_TRACK_BUF(buf, drv, value, info) do{}while(0) +#define GBPM_TRACK_SKB(skb, drv, value, info) do{}while(0) +#define GBPM_TRACK_FKB(fkb, drv, value, info) do{}while(0) +#define GBPM_INC_REF(buf) do{}while(0) +#define GBPM_DEC_REF(buf) do{}while(0) +#endif + +#endif /* defined(__GBPM_H_INCLUDED__) */ diff --git a/include/linux/iqos.h b/include/linux/iqos.h new file mode 100644 index 0000000000000000000000000000000000000000..58440890fbffd163d197a7f4f9cda80b1289d6b2 --- /dev/null +++ b/include/linux/iqos.h @@ -0,0 +1,268 @@ +#ifndef __IQOS_H_INCLUDED__ +#define __IQOS_H_INCLUDED__ + +/* +<:copyright-BRCM:2009:DUAL/GPL:standard + + Copyright (c) 2009 Broadcom + All Rights Reserved + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + + +/* + ******************************************************************************* + * File Name : ingqos.h + * + ******************************************************************************* + */ +#define IQOS_VERSION "v1.0" +#define IQOS_VER_STR IQOS_VERSION +#define IQOS_MODNAME "Broadcom IQoS " + +#include <linux/if_ether.h> + +typedef enum { + IQOS_PARAM_TYPE_KEYMASK, + IQOS_PARAM_TYPE_KEY, + IQOS_PARAM_TYPE_MAX +} iqos_param_type_t; + +typedef enum { + IQOS_FIELD_INGRESS_DEVICE, + IQOS_FIELD_SRC_MAC, + IQOS_FIELD_DST_MAC, + IQOS_FIELD_ETHER_TYPE, + IQOS_FIELD_OUTER_VID, + IQOS_FIELD_OUTER_PBIT, + IQOS_FIELD_INNER_VID, + IQOS_FIELD_INNER_PBIT, + IQOS_FIELD_L2_PROTO, + IQOS_FIELD_L3_PROTO, + IQOS_FIELD_IP_PROTO, + IQOS_FIELD_SRC_IP, + IQOS_FIELD_DST_IP, + IQOS_FIELD_DSCP, + IQOS_FIELD_IPV6_FLOW_LABEL, + IQOS_FIELD_SRC_PORT, + IQOS_FIELD_DST_PORT, + IQOS_FIELD_OFFSET_0, + IQOS_FIELD_OFFSET_START = IQOS_FIELD_OFFSET_0, + IQOS_FIELD_OFFSET_0_TYPE, + IQOS_FIELD_OFFSET_0_START, + IQOS_FIELD_OFFSET_0_SIZE, + IQOS_FIELD_OFFSET_0_MASK, + IQOS_FIELD_OFFSET_1, + IQOS_FIELD_OFFSET_1_TYPE, + IQOS_FIELD_OFFSET_1_START, + IQOS_FIELD_OFFSET_1_SIZE, + IQOS_FIELD_OFFSET_1_MASK, + IQOS_FIELD_OFFSET_END = IQOS_FIELD_OFFSET_1_MASK, + IQOS_FIELD_MAX +} iqos_field_t; + +typedef enum { + IQOS_ACTION_NOP, + IQOS_ACTION_PRIO, + IQOS_ACTION_DROP, + IQOS_ACTION_DST_Q, + IQOS_ACTION_TRAP, + IQOS_ACTION_MAX +} iqos_action_t; + +typedef enum { + IQOS_OFFSET_TYPE_L2, + IQOS_OFFSET_TYPE_L3, + IQOS_OFFSET_TYPE_L4, + IQOS_OFFSET_TYPE_MAX +} iqos_offset_type_t; + +typedef struct { + uint32_t type; + uint32_t start; + uint32_t size; + uint32_t mask; +} iqos_offset_data_t; + +#define IQOS_PACKET_CACHE_MAX_SIZE 128 +typedef struct { + uint32_t ingress_device; + uint8_t src_mac[ETH_HLEN]; + uint8_t dst_mac[ETH_HLEN]; + uint16_t eth_type; + uint16_t outer_vid; + uint8_t outer_pbit; + uint16_t inner_vid; + uint8_t inner_pbit; + uint16_t l2_proto; + uint16_t l3_proto; + uint8_t ip_proto; + uint8_t is_ipv6; + uint32_t src_ip[4]; + uint32_t dst_ip[4]; + uint8_t dscp; + uint32_t flow_label; + uint16_t l4_src_port; + uint16_t l4_dst_port; + uint16_t l2_offset; + uint16_t l3_offset; + uint16_t l4_offset; + /* used for storing part of packet buffer for offset check */ + uint8_t packet_cache[IQOS_PACKET_CACHE_MAX_SIZE]; +} iqos_data_t; + +typedef struct { + uint32_t param_type; + uint8_t prio; + uint8_t type; + uint32_t field_mask; + uint32_t action; + uint32_t action_value; + iqos_data_t data; + iqos_offset_data_t offset0; + iqos_offset_data_t offset1; +} iqos_param_t; + +typedef enum { + IQOS_ENT_DYN, + IQOS_ENT_STAT, + IQOS_ENT_MAX +} iqos_ent_t; + +typedef enum { + IQOS_PRIO_LOW, + IQOS_PRIO_HIGH, + IQOS_PRIO_MAX +} iqos_prio_t; + +typedef enum { + IQOS_CONG_STATUS_LO, + IQOS_CONG_STATUS_HI, + IQOS_CONG_STATUS_MAX +} iqos_cong_status_t; + +typedef enum { + IQOS_STATUS_DISABLE, + IQOS_STATUS_ENABLE, + IQOS_STATUS_MAX +} iqos_status_t; + +typedef struct { + uint8_t ipProto; + uint16_t destPort; + iqos_ent_t ent; + iqos_prio_t prio; +} iqos_config_t; + +typedef int (*iqos_common_hook_t)(iqos_param_t *param); +typedef void (*iqos_void_hook_t)(void); +typedef int (*iqos_int_hook_t)(uint32_t val); + +/* the original APIs that are backward supported by the new driver/module */ +int iqos_add_L4port(uint8_t ipProto, uint16_t destPort, iqos_ent_t ent, + iqos_prio_t prio); +int iqos_rem_L4port(uint8_t ipProto, uint16_t destPort, iqos_ent_t ent); +int iqos_prio_L4port(uint8_t ipProto, uint16_t destPort); + +/* the new APIs */ + +/* APIs for setting up keymask: + * WARNING!! one will have to perform iqos_flush() to delete all the dynamic + * entry before making any change of the keymasks. + * Deleting a keymask that has key refer to it will fail and return error */ +int iqos_keymask_param_start(iqos_param_t *param); +int iqos_keymask_param_field_set(iqos_param_t *param, uint32_t field, uint32_t *val_ptr); +int iqos_keymask_commit_and_add(iqos_param_t *param, uint8_t prio); +int iqos_keymask_commit_and_delete(iqos_param_t *param); + +/* APIs for setting up key, + * example can be found in iqos_[add/rem/prio]_L4port */ +int iqos_key_param_start(iqos_param_t *param); +int iqos_key_param_field_set(iqos_param_t *param, uint32_t field, + uint32_t *val_ptr, uint32_t val_size); +int iqos_key_param_action_set(iqos_param_t *param, uint32_t action, + uint32_t value); +int iqos_key_commit_and_add(iqos_param_t *param, uint8_t type); +int iqos_key_commit_and_delete(iqos_param_t *param, uint8_t type); +int iqos_key_commit_and_get(iqos_param_t *param); + +/* API to flush all the dynamic entries, and + * delete keymask if no key refers to it */ +void iqos_flush(void); + +/* API to set the status for IQOS to enabled(1) or disabled(0) */ +int iqos_set_status(uint32_t status); + +void iqos_bind(iqos_common_hook_t iqos_add_keymask, + iqos_common_hook_t iqos_rem_keymask, + iqos_common_hook_t iqos_add_key, + iqos_common_hook_t iqos_rem_key, + iqos_common_hook_t iqos_get_key, + iqos_int_hook_t iqos_set_status, + iqos_void_hook_t iqos_flush); + + +#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) +#define IQOS_LOCK_IRQSAVE() spin_lock_irqsave( &iqos_cong_lock_g, flags ) +#define IQOS_UNLOCK_IRQRESTORE() spin_unlock_irqrestore( &iqos_cong_lock_g, flags ) +#define IQOS_LOCK_BH() spin_lock_bh( &iqos_lock_g ) +#define IQOS_UNLOCK_BH() spin_unlock_bh( &iqos_lock_g ) +#else +#define IQOS_LOCK_IRQSAVE() local_irq_save(flags) +#define IQOS_UNLOCK_IRQRESTORE() local_irq_restore(flags) +#define IQOS_LOCK_BH() NULL_STMT +#define IQOS_UNLOCK_BH() NULL_STMT +#endif + +#if IS_ENABLED(CONFIG_BCM_INGQOS) +#define IQOS_RXCHNL_MAX 4 +#define IQOS_RXCHNL_DISABLED 0 +#define IQOS_RXCHNL_ENABLED 1 +#define IQOS_MAX_RX_RING_SIZE 4096 + +typedef enum { + IQOS_IF_ENET, + IQOS_IF_ENET_RXCHNL0 = IQOS_IF_ENET, + IQOS_IF_ENET_RXCHNL1, + IQOS_IF_ENET_RXCHNL2, + IQOS_IF_ENET_RXCHNL3, + IQOS_IF_XTM, + IQOS_IF_XTM_RXCHNL0 = IQOS_IF_XTM, + IQOS_IF_XTM_RXCHNL1, + IQOS_IF_XTM_RXCHNL2, + IQOS_IF_XTM_RXCHNL3, + IQOS_IF_FWD, + IQOS_IF_FWD_RXCHNL0 = IQOS_IF_FWD, + IQOS_IF_FWD_RXCHNL1, + IQOS_IF_WL, + IQOS_IF_USB, + IQOS_IF_MAX, +} iqos_if_t; + +iqos_cong_status_t iqos_get_sys_cong_status(void); +iqos_cong_status_t iqos_get_cong_status(iqos_if_t iface, uint32_t chnl); +uint32_t iqos_set_cong_status(iqos_if_t iface, uint32_t chnl, + iqos_cong_status_t status); +#endif +#endif /* defined(__IQOS_H_INCLUDED__) */ diff --git a/include/linux/nbuff.h b/include/linux/nbuff.h new file mode 100755 index 0000000000000000000000000000000000000000..e0fb6ec30ed94b0125616a988b04c3eb27eca24e --- /dev/null +++ b/include/linux/nbuff.h @@ -0,0 +1,1793 @@ +#ifndef __NBUFF_H_INCLUDED__ +#define __NBUFF_H_INCLUDED__ + + +/* +<:copyright-BRCM:2013:DUAL/GPL:standard + + Copyright (c) 2013 Broadcom + All Rights Reserved + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + +/* + ******************************************************************************* + * + * File Name : nbuff.h + * Description: Definition of a network buffer to support various forms of + * network buffer, to include Linux socket buff (SKB), lightweight + * fast kernel buff (FKB), BRCM Free Pool buffer (FPB), and traffic + * generator support buffer (TGB) + * + * nbuff.h may also be used to provide an interface to common APIs + * available on other OS (in particular BSD style mbuf). + * + * Common APIs provided: pushing, pulling, reading, writing, cloning, freeing + * + * Implementation Note: + * + * One may view NBuff as a base class from which other buff types are derived. + * Examples of derived network buffer types are sk_buff, fkbuff, fpbuff, tgbuff + * + * A pointer to a buffer is converted to a pointer to a special (derived) + * network buffer type by encoding the type into the least significant 2 bits + * of a word aligned buffer pointer. pBuf points to the real network + * buffer and pNBuff refers to pBuf ANDed with the Network Buffer Type. + * C++ this pointer to a virtual class (vtable based virtual function thunks). + * + * Thunk functions to redirect the calls to the appropriate buffer type, e.g. + * SKB or FKB uses the Network Buffer Pointer type information. + * + * This file also implements the Fast Kernel Buffer API. The fast kernel buffer + * carries a minimal context of the received buffer and associated buffer + * recycling information. + * + ******************************************************************************* */ + +#include <linux/version.h> +#include <generated/autoconf.h> +#include <linux/types.h> /* include ISO C99 inttypes.h */ +#include <linux/skbuff.h> /* include corresponding BSD style mbuf */ +#include <bcm_pkt_lengths.h> +#include <linux/netdevice.h> + +#ifdef CONFIG_BLOG +#include <linux/blog.h> +#endif +#include <linux/blog_net.h> /*TODO rename this file as bcm_net.h as it's not specific to blog */ + +#define NBUFF_VERSION "v1.0" + +#if defined(CONFIG_BCM96855) +// temporary untill network is enabled +#define CONFIG_BCM_MAX_MCAST_GROUPS 1 +#define CONFIG_BCM_MAX_MCAST_CLIENTS 1 +#endif + +/* Engineering Constants for Fast Kernel Buffer Global Pool (used for clones) */ +#define SUPPORT_FKB_EXTEND +#define FKBC_POOL_SIZE_ENGG (2080) /*1280 more to be allocated for wireless*/ +#define FKBC_EXTEND_SIZE_ENGG 32 /* Number of FkBuf_t per extension*/ +#define FKBC_EXTEND_MAX_ENGG 16 /* Maximum extensions allowed */ + +#define FKBM_POOL_SIZE_ENGG 128 +#define FKBM_EXTEND_SIZE_ENGG 32 +#define FKBM_EXTEND_MAX_ENGG \ + (((CONFIG_BCM_MAX_MCAST_GROUPS * (CONFIG_BCM_MAX_MCAST_CLIENTS+1))/FKBM_EXTEND_SIZE_ENGG) + 1) + +/* + * Network device drivers ported to NBUFF must ensure that the headroom is at + * least 186 bytes in size. Remove this dependancy (TBD). + */ +// #define CC_FKB_HEADROOM_AUDIT + +/* Conditional compile of FKB functional APIs as inlined or non-inlined */ +#define CC_CONFIG_FKB_FN_INLINE +#ifdef CC_CONFIG_FKB_FN_INLINE +#define FKB_FN(fn_name, fn_signature, body) \ +static inline fn_signature { body; } /* APIs inlined in header file */ +#else +#ifdef FKB_IMPLEMENTATION_FILE +#define FKB_FN(fn_name, fn_signature, body) \ +fn_signature { body; } \ +EXPORT_SYMBOL(fn_name); /* APIs declared in implementation */ +#else +#define FKB_FN(fn_name, fn_signature, body) \ +extern fn_signature; +#endif /* !defined(FKB_IMPLEMENTATION_FILE) */ +#endif /* !defined(FKB_FN) */ + +/* LAB ONLY: Design development */ +//#define CC_CONFIG_FKB_STATS +//#define CC_CONFIG_FKB_COLOR +//#define CC_CONFIG_FKB_DEBUG +//#define CC_CONFIG_FKB_AUDIT +//#define CC_CONFIG_FKB_STACK + +// #include <linux/smp.h> /* smp_processor_id() CC_CONFIG_FKB_AUDIT */ + +#if defined(CC_CONFIG_FKB_STATS) +#define FKB_STATS(stats_code) do { stats_code } while(0) +#else +#define FKB_STATS(stats_code) NULL_STMT +#endif + +#if defined(CC_CONFIG_FKB_STACK) +extern void dump_stack(void); +#define DUMP_STACK() dump_stack() +#else +#define DUMP_STACK() NULL_STMT +#endif + +#if defined(CC_CONFIG_FKB_AUDIT) +#define FKB_AUDIT(audit_code) do { audit_code } while(0) +#else +#define FKB_AUDIT(audit_code) NULL_STMT +#endif + +extern int nbuff_dbg; +#if defined(CC_CONFIG_FKB_DEBUG) +#define fkb_dbg(lvl, fmt, arg...) \ + if (nbuff_dbg >= lvl) printk( "FKB %s :" fmt "[<%pS>]\n", \ + __FUNCTION__, ##arg, __builtin_return_address(0) ) +#define FKB_DBG(debug_code) do { debug_code } while(0) +#else +#define fkb_dbg(lvl, fmt, arg...) do {} while(0) +#define FKB_DBG(debug_code) NULL_STMT +#endif + +#define CC_NBUFF_FLUSH_OPTIMIZATION + +/* CACHE OPERATIONS */ +#define FKB_CACHE_FLUSH 0 +#define FKB_CACHE_INV 1 + +/* OS Specific Section Begin */ +#if defined(__KERNEL__) /* Linux Cache Specific */ +/* + *------------------------------------------------------------------------------ + * common cache operations: + * + * - addr is rounded down to the cache line + * - end is rounded up to cache line. + * + * - if ((addr == end) and (addr was cache aligned before rounding)) + * no operation is performed. + * else + * flush data cache line UPTO but NOT INCLUDING rounded up end. + * + * Note: + * if before rounding, (addr == end) AND addr was not cache aligned, + * we would flush at least one line. + * + * Uses: L1_CACHE_BYTES + *------------------------------------------------------------------------------ + */ +#include <asm/cache.h> + +extern void cache_flush_data_len(void *addr, int len); + +/* + * Macros to round down and up, an address to a cachealigned address + */ +#define ADDR_ALIGN_DN(addr, align) ( (addr) & ~((align) - 1) ) +#define ADDR_ALIGN_UP(addr, align) ( ((addr) + (align) - 1) & ~((align) - 1) ) + +#if defined(CONFIG_ARM) + +#include <asm/cacheflush.h> + +#ifdef CONFIG_CPU_CACHE_V7 +#define __cpuc_flush_line(_addr) \ + __asm__ __volatile__("mcr p15, 0, %0, c7, c14, 1" : : "r" (_addr)) +#define __cpuc_clean_line(_addr) \ + __asm__ __volatile__("mcr p15, 0, %0, c7, c10, 1" : : "r" (_addr)) +#define __cpuc_inv_line(_addr) \ + __asm__ __volatile__("mcr p15, 0, %0, c7, c6, 1" : : "r" (_addr)) +#else +#define __cpuc_flush_line(_addr) do {} while(0) +#define __cpuc_clean_line(_addr) do {} while(0) +#define __cpuc_inv_line(_addr) do {} while(0) +#endif + +#if defined(CONFIG_ARM_L1_CACHE_SHIFT) +#define L1_CACHE_LINE_SIZE (0x1 << CONFIG_ARM_L1_CACHE_SHIFT) +#else +#warning There is no L1 cache line size defined! +#endif + +#if defined(CONFIG_OUTER_CACHE) + +#if defined(CONFIG_CACHE_L2X0) +#define L2_CACHE_LINE_SIZE 32 +#endif + +#if defined(L2_CACHE_LINE_SIZE) && (L1_CACHE_LINE_SIZE != L2_CACHE_LINE_SIZE) +#warning L1 Cache line size is different from L2 cache line size! +#endif + +#define CONFIG_OPTIMIZED_CACHE_FLUSH 1 +#endif + +static inline void cache_flush_len(void *addr, int len); +static inline void _cache_flush_len(void *addr, int len); + +#ifdef CONFIG_BCM_GLB_COHERENCY +#define cache_invalidate_len_outer_first(virt_addr, len) +#define cache_invalidate_region_outer_first(virt_addr, end) +#define cache_invalidate_len(virt_addr, len) +#define cache_invalidate_region(virt_addr, end) +#define cache_flush_region(addr, end) +#else + +/* the following functions are optimized that it does NOT support + * HIGHMEM in 32-bit system, please make sure buffer allocated + * are in memory zone 'Normal' or before */ +static inline void cache_invalidate_len_outer_first(void *virt_addr, int len) +{ + uintptr_t start_vaddr = (uintptr_t)virt_addr; + uintptr_t end_vaddr = start_vaddr + len; +#if defined(CONFIG_OUTER_CACHE) + uintptr_t start_paddr = virt_to_phys(virt_addr); + uintptr_t end_paddr = start_paddr + len; +#endif + +#if defined(CONFIG_OUTER_CACHE) + outer_spin_lock_irqsave(); +#endif + /* 1st, flush & invalidate if start addr and / or end addr are not + * cache line aligned */ + if (start_vaddr & (L1_CACHE_LINE_SIZE - 1)) { + start_vaddr &= ~(L1_CACHE_LINE_SIZE - 1); + __cpuc_flush_line(start_vaddr); +#if defined(CONFIG_OUTER_CACHE) + dsb(); +#endif + start_vaddr += L1_CACHE_LINE_SIZE; + } + +#if defined(CONFIG_OUTER_CACHE) + if (start_paddr & (L2_CACHE_LINE_SIZE - 1)) { + start_paddr &= ~(L2_CACHE_LINE_SIZE - 1); + outer_flush_line_no_lock(start_paddr); + outer_sync_no_lock(); + start_paddr += L2_CACHE_LINE_SIZE; + } +#endif + + if (end_vaddr & (L1_CACHE_LINE_SIZE - 1)) { + end_vaddr &= ~(L1_CACHE_LINE_SIZE - 1); + __cpuc_flush_line(end_vaddr); +#if defined(CONFIG_OUTER_CACHE) + dsb(); +#endif + } + +#if defined(CONFIG_OUTER_CACHE) + if (end_paddr & (L2_CACHE_LINE_SIZE - 1)) { + end_paddr &= ~(L2_CACHE_LINE_SIZE - 1); + outer_flush_line_no_lock(end_paddr); + outer_sync_no_lock(); + } +#endif + +#if defined(CONFIG_OUTER_CACHE) + /* now do the real invalidation jobs */ + while (start_paddr < end_paddr) { + outer_inv_line_no_lock(start_paddr); + start_paddr += L2_CACHE_LINE_SIZE; + } + outer_sync_no_lock(); +#endif + + /* now do the real invalidation jobs */ + while (start_vaddr < end_vaddr) { + __cpuc_inv_line(start_vaddr); + start_vaddr += L1_CACHE_LINE_SIZE; + } + + dsb(); +#if defined(CONFIG_OUTER_CACHE) + outer_spin_unlock_irqrestore(); +#endif + + if ((len >= PAGE_SIZE) && (((uintptr_t)virt_addr & ~PAGE_MASK) == 0)) + set_bit(PG_dcache_clean, &phys_to_page(virt_to_phys(virt_addr))->flags); +} + +static inline void cache_invalidate_region_outer_first(void *virt_addr, void *end) +{ + cache_invalidate_len_outer_first(virt_addr, + (uintptr_t)end - (uintptr_t)virt_addr); +} + +static inline void cache_invalidate_len(void *virt_addr, int len) +{ + uintptr_t start_vaddr = (uintptr_t)virt_addr; + uintptr_t end_vaddr = start_vaddr + len; +#if defined(CONFIG_OUTER_CACHE) + uintptr_t start_paddr = virt_to_phys(virt_addr); + uintptr_t end_paddr = start_paddr + len; +#endif + +#if defined(CONFIG_OUTER_CACHE) + outer_spin_lock_irqsave(); +#endif + /* 1st, flush & invalidate if start addr and / or end addr are not + * cache line aligned */ + if (start_vaddr & (L1_CACHE_LINE_SIZE - 1)) { + start_vaddr &= ~(L1_CACHE_LINE_SIZE - 1); + __cpuc_flush_line(start_vaddr); +#if defined(CONFIG_OUTER_CACHE) + dsb(); +#endif + start_vaddr += L1_CACHE_LINE_SIZE; + } + +#if defined(CONFIG_OUTER_CACHE) + if (start_paddr & (L2_CACHE_LINE_SIZE - 1)) { + start_paddr &= ~(L2_CACHE_LINE_SIZE - 1); + outer_flush_line_no_lock(start_paddr); + start_paddr += L2_CACHE_LINE_SIZE; + } +#endif + + if (end_vaddr & (L1_CACHE_LINE_SIZE - 1)) { + end_vaddr &= ~(L1_CACHE_LINE_SIZE - 1); + __cpuc_flush_line(end_vaddr); +#if defined(CONFIG_OUTER_CACHE) + dsb(); +#endif + } + +#if defined(CONFIG_OUTER_CACHE) + if (end_paddr & (L2_CACHE_LINE_SIZE - 1)) { + end_paddr &= ~(L2_CACHE_LINE_SIZE - 1); + outer_flush_line_no_lock(end_paddr); + } +#endif + + /* now do the real invalidation jobs */ + while (start_vaddr < end_vaddr) { + __cpuc_inv_line(start_vaddr); +#if defined(CONFIG_OUTER_CACHE) + dsb(); + outer_inv_line_no_lock(start_paddr); + start_paddr += L2_CACHE_LINE_SIZE; +#endif + start_vaddr += L1_CACHE_LINE_SIZE; + } +#if defined(CONFIG_OUTER_CACHE) + outer_sync_no_lock(); + outer_spin_unlock_irqrestore(); +#else + dsb(); +#endif + + if ((len >= PAGE_SIZE) && (((uintptr_t)virt_addr & ~PAGE_MASK) == 0)) + set_bit(PG_dcache_clean, &phys_to_page(virt_to_phys(virt_addr))->flags); +} + +static inline void cache_invalidate_region(void *virt_addr, void *end) +{ + cache_invalidate_len(virt_addr, + (uintptr_t)end - (uintptr_t)virt_addr); +} + +static inline void cache_flush_region(void *addr, void *end) +{ + cache_flush_len(addr, (uintptr_t)end - (uintptr_t)addr); +} + +#endif /* CONFIG_BCM_GLB_COHERENCY */ + +static inline void cache_flush_len(void *addr, int len) +{ +#ifndef CONFIG_BCM_GLB_COHERENCY + _cache_flush_len(addr, len); +#endif +} +static inline void fpm_cache_flush_len(void *addr, int len) +{ +#if !defined(CONFIG_BCM_GLB_COHERENCY) || defined(CONFIG_BCM_FPM_COHERENCY_EXCLUDE) + _cache_flush_len(addr, len); +#endif +} + +static inline void _cache_flush_len(void *addr, int len) +{ + uintptr_t start_vaddr = (uintptr_t)addr & ~(L1_CACHE_LINE_SIZE - 1); + uintptr_t end_vaddr = (uintptr_t)addr + len; +#if defined(CONFIG_OUTER_CACHE) + uintptr_t start_paddr = (uintptr_t)virt_to_phys((void *)start_vaddr); +#endif + +#if defined(CONFIG_OUTER_CACHE) + outer_spin_lock_irqsave(); +#endif +#if defined(CONFIG_OPTIMIZED_CACHE_FLUSH) + /* this function has been optimized in a non-recommended way, if any + * type of packet error occurs, please try undefine + * CONFIG_OPTIMIZED_CACHE_FLUSH to use the recommended algorithm + * provided by ARM cache document. + * Usually, when we have multiple levels of cache, in a cache_flush + * case, we do L1_clean -> L2_clean -> L2_invalidate -> L1_clean + * -> L1_invalidate, we can optimize this sequence to L1_clean -> + * L2_flush -> L1_flush. This is our original approach. However, + * this will introduce 3 loops of cache operation. + * This optimized method will do L1_flush -> L2_flush. This will only + * introduce 2 loops of cache operation, but it also puts us into + * danger that L2 cache might update L1 cache on the cache line + * that should have been invalidated. */ + + while (start_vaddr < end_vaddr) { + __cpuc_flush_line(start_vaddr); + start_vaddr += L1_CACHE_LINE_SIZE; +#if defined(CONFIG_OUTER_CACHE) + dsb(); + outer_flush_line_no_lock(start_paddr); + start_paddr += L2_CACHE_LINE_SIZE; +#endif + } +#if defined(CONFIG_OUTER_CACHE) + outer_sync_no_lock(); +#else + wmb(); +#endif +#else /* the non-optimized cache_flush */ + while (start_vaddr < end_vaddr) { +#if defined(CONFIG_OUTER_CACHE) + __cpuc_clean_line(start_vaddr); + dsb(); + outer_flush_line_no_lock(start_paddr); + start_paddr += L2_CACHE_LINE_SIZE; + outer_sync_no_lock(); +#endif + __cpuc_flush_line(start_vaddr); + start_vaddr += L1_CACHE_LINE_SIZE; + } + wmb(); +#endif +#if defined(CONFIG_OUTER_CACHE) + outer_spin_unlock_irqrestore(); +#endif +} + + +static inline uint32_t _is_kptr_(const void * vptr) +{ + return ( (uintptr_t)vptr > 0x0FFFFFFF ); +} + +#elif defined(CONFIG_ARM64) + +#define nbuff_flush_dcache_area(addr, len) \ + __asm__ __volatile__ ( \ + "mov x0, %0 \n" \ + "mov x1, %1 \n" \ + "mrs x3, ctr_el0 \n" \ + "ubfm x3, x3, #16, #19 \n" \ + "mov x2, #4 \n" \ + "lsl x2, x2, x3 \n" \ + "add x1, x0, x1 \n" \ + "sub x3, x2, #1 \n" \ + "bic x0, x0, x3 \n" \ + "1: dc civac, x0 \n" \ + "add x0, x0, x2 \n" \ + "cmp x0, x1 \n" \ + "b.lo 1b \n" \ + "dsb sy \n" \ + : : "r" ((uintptr_t)addr), "r" ((uintptr_t)len) \ + : "x0", "x1", "x2", "x3", "cc") + +#define nbuff_inval_dcache_range(start, end) \ + __asm__ __volatile__ ( \ + "mov x0, %0 \n" \ + "mov x1, %1 \n" \ + "mrs x3, ctr_el0 \n" \ + "ubfm x3, x3, #16, #19 \n" \ + "mov x2, #4 \n" \ + "lsl x2, x2, x3 \n" \ + "sub x3, x2, #1 \n" \ + "tst x1, x3 \n" \ + "bic x1, x1, x3 \n" \ + "b.eq 1f \n" \ + "dc civac, x1 \n" \ + "1: tst x0, x3 \n" \ + "bic x0, x0, x3 \n" \ + "b.eq 2f \n" \ + "dc civac, x0 \n" \ + "b 3f \n" \ + "2: dc ivac, x0 \n" \ + "3: add x0, x0, x2 \n" \ + "cmp x0, x1 \n" \ + "b.lo 2b \n" \ + "dsb sy \n" \ + : : "r" ((uintptr_t)start), "r" ((uintptr_t)end)\ + : "x0", "x1", "x2", "x3", "cc") + +static inline void cache_flush_region(void *addr, void *end) +{ +#ifndef CONFIG_BCM_GLB_COHERENCY + nbuff_flush_dcache_area(addr, (uintptr_t)end - (uintptr_t)addr); +#endif +} + +static inline void cache_flush_len(void *addr, int len) +{ +#ifndef CONFIG_BCM_GLB_COHERENCY + nbuff_flush_dcache_area(addr, len); +#endif +} + +static inline void fpm_cache_flush_len(void *addr, int len) +{ +#if !defined(CONFIG_BCM_GLB_COHERENCY) || defined(CONFIG_BCM_FPM_COHERENCY_EXCLUDE) + nbuff_flush_dcache_area(addr, len); +#endif +} + +static inline void cache_invalidate_region(void *addr, void *end) +{ +#ifndef CONFIG_BCM_GLB_COHERENCY + nbuff_inval_dcache_range(addr, end); +#endif +} + +static inline void cache_invalidate_len(void *addr, int len) +{ +#ifndef CONFIG_BCM_GLB_COHERENCY + nbuff_inval_dcache_range(addr, (void*)((uintptr_t)addr+len)); +#endif +} + +#define cache_invalidate_region_outer_first(a, b) cache_invalidate_region(a, b) +#define cache_invalidate_len_outer_first(a, b) cache_invalidate_len(a, b) + +static inline uint32_t _is_kptr_(const void * vptr) +{ + return ( (uintptr_t)vptr > 0xFFFFFF8000000000 ); +} +#endif + +#endif /* defined(__KERNEL__) Linux MIPS Cache Specific */ +/* OS Specific Section End */ + + +/* + * For BSD style mbuf with FKB : + * generate nbuff.h by replacing "SKBUFF" to "BCMMBUF", and, + * use custom arg1 and arg2 instead of mark and priority, respectively. + */ + +#ifdef TRACE_COMPILE +#pragma message "got here 4" +#endif + +struct sk_buff; +#if defined(CONFIG_BLOG) +struct blog_t; +#endif +struct net_device; +typedef int (*HardStartXmitFuncP) (struct sk_buff *skb, + struct net_device *dev); + +struct fkbuff; +typedef struct fkbuff FkBuff_t; + +#define FKB_NULL ((FkBuff_t *)NULL) + +#include <linux/nbuff_types.h> + +/* + *------------------------------------------------------------------------------ + * + * Pointer conversion between pBuf and pNBuff encoded buffer pointers + * uint8_t * pBuf; + * pNBuff_t pNBuff; + * ... + * // overlays FKBUFF_PTR into pointer to build a virtual pNBuff_t + * pNBuff = PBUF_2_PNBUFF(pBuf,FKBUFF_PTR); + * ... + * // extracts a real uint8_t * from a virtual pNBuff_t + * pBuf = PNBUFF_2_PBUF(pNBuff); + * + *------------------------------------------------------------------------------ + */ +#define PBUF_2_PNBUFF(pBuf,realType) \ + ( (pNBuff_t) ((uintptr_t)(pBuf) | (uintptr_t)(realType)) ) +#define PNBUFF_2_PBUF(pNBuff) \ + ( (uint8_t*) ((uintptr_t)(pNBuff) & (uintptr_t)NBUFF_PTR_MASK) ) + +#if (MUST_BE_ZERO != 0) +#error "Design assumption SKBUFF_PTR == 0" +#endif +#define PNBUFF_2_SKBUFF(pNBuff) ((struct sk_buff *)(pNBuff)) + +#define SKBUFF_2_PNBUFF(skb) ((pNBuff_t)(skb)) /* see MUST_BE_ZERO */ +#define FKBUFF_2_PNBUFF(fkb) PBUF_2_PNBUFF(fkb,FKBUFF_PTR) + +/* + *------------------------------------------------------------------------------ + * + * Cast from/to virtual "pNBuff_t" to/from real typed pointers + * + * pNBuff_t pNBuff2Skb, pNBuff2Fkb; // "void *" with NBuffPtrType_t + * struct sk_buff * skb_p; + * struct fkbuff * fkb_p; + * ... + * pNBuff2Skb = CAST_REAL_TO_VIRT_PNBUFF(skb_p,SKBUFF_PTR); + * pNBuff2Fkb = CAST_REAL_TO_VIRT_PNBUFF(fkb_p,FKBUFF_PTR); + * ... + * skb_p = CAST_VIRT_TO_REAL_PNBUFF(pNBuff2Skb, struct sk_buff *); + * fkb_p = CAST_VIRT_TO_REAL_PNBUFF(pNBuff2Fkb, struct fkbuff *); + * or, + * fkb_p = PNBUFF_2_FKBUFF(pNBuff2Fkb); + *------------------------------------------------------------------------------ + */ + +#define CAST_REAL_TO_VIRT_PNBUFF(pRealNBuff,realType) \ + ( (pNBuff_t) (PBUF_2_PNBUFF((pRealNBuff),(realType))) ) + +#define CAST_VIRT_TO_REAL_PNBUFF(pVirtNBuff,realType) \ + ( (realType) PNBUFF_2_PBUF(pVirtNBuff) ) + +#define PNBUFF_2_FKBUFF(pNBuff) CAST_VIRT_TO_REAL_PNBUFF((pNBuff), struct fkbuff*) + + + +/* + *------------------------------------------------------------------------------ + * FKB: Fast Kernel Buffers placed directly into Rx DMA Buffer + * May be used ONLY for common APIs such as those available in BSD-Style mbuf + *------------------------------------------------------------------------------ + */ + +struct fkbuff +{ + /* List pointer must be the first field */ + union { + void * word0; + FkBuff_t * list; /* SLL of free FKBs for cloning */ + FkBuff_t * master_p; /* Clone FKB to point to master FKB */ + atomic_long_t users; /* (private) # of references to FKB */ + }; + union { /* Use _is_kptr_ to determine if ptr */ + union { + void *ptr; + struct blog_t *blog_p; /* Pointer to a blog */ + uint8_t *dirty_p; /* Pointer to packet payload dirty incache*/ + uint32_t flags; /* Access all flags */ + }; + /* + * First nibble denotes a pointer or flag usage. + * Lowest two significant bits denote the type of pinter + * Remaining 22 bits may be used as flags + */ + struct { + uint32_t ptr_type : 8;/* Identifies whether pointer */ + uint32_t unused :21;/* Future use for flags */ + uint32_t in_skb : 1;/* flag: FKB passed inside a SKB */ + uint32_t other_ptr: 1;/* future use, to override another pointer*/ + uint32_t dptr_tag : 1;/* Pointer type is a dirty pointer */ + }; + }; + uint8_t * data; /* Pointer to packet data */ + + union { + /* here the bits 31-24 are valid only for native fkbs's + * these bits bits will be cleared when using fkbInSkb + * Note that it is critical to have the Little Endian/Big endian + * declaration since FKB will use length as bit field and SKB will use + * length as a word Need to maintain the same bit positions across MIPS + * and ARM. + */ + struct{ + BE_DECL( + uint32_t rx_csum_verified:1; + uint32_t spdtst:1; + uint32_t reserved:6; + uint32_t len:24; /* Packet length */ + ) + LE_DECL( + uint32_t len:24; + uint32_t reserved:6; + uint32_t spdtst:1; + uint32_t rx_csum_verified:1; + ) + }; + uint32_t len_word; + }; + + union { + /* only the lower 32 bit in mark is used in 64 bit system, + * but we delcare it as unsigned long for the ease for fcache + * to handle it in different architecture, since it is part + * of union with a dst_entry pointer */ + unsigned long mark; /* Custom arg1, e.g. tag or mark field */ + void *queue; /* Single link list queue of FKB | SKB */ + void *dst_entry; /* rtcache entry for locally termiated pkts */ + uint32_t fc_ctxt; /* hybrid flow cache context */ + }; + union { + uint32_t priority; /* Custom arg2, packet priority, tx info */ + /*TODO define wl as just uint32_t */ + wlFlowInf_t wl; /* WLAN Flow Info */ + uint32_t flowid; /* used for locally terminated pkts */ + }; + + RecycleFuncP recycle_hook; /* Nbuff recycle handler */ + union { + /* recycle hook for Clone FKB is used in DHD pointing to extra info + * BE CAREFULL when using this recyle_context for free etc.... + */ + void *dhd_pkttag_info_p; + unsigned long recycle_context; /* Rx network device/channel or pool */ + uint32_t fpm_num; + }; + +} ____cacheline_aligned; /* 2 cache lines wide */ + +#define FKB_CLEAR_LEN_WORD_FLAGS(len_word) (len_word &= 0x00FFFFFF) + + +/* + *------------------------------------------------------------------------------ + * An fkbuff may be referred to as a: + * master - a pre-allocated rxBuffer, inplaced ahead of the headroom. + * cloned - allocated from a free pool of fkbuff and points to a master. + * + * in_skb - when a FKB is passed as a member of a SKB structure. + *------------------------------------------------------------------------------ + */ +#define FKB_IN_SKB (1 << 2) /* Bit#2 is in_skb */ + +/* Return flags with the in_skb tag set */ +static inline uint32_t _set_in_skb_tag_(uint32_t flags) +{ + return (flags | FKB_IN_SKB); +} + +/* Fetch the in_skb tag in flags */ +static inline uint32_t _get_in_skb_tag_(void *ptr, uint32_t flags) +{ + if (_is_kptr_(ptr)) + return 0; + return (flags & FKB_IN_SKB); +} + +/* Determine whether the in_skb tag is set in flags */ +static inline uint32_t _is_in_skb_tag_(void *ptr, uint32_t flags) +{ + return ( _get_in_skb_tag_(ptr, flags) ? 1 : 0 ); +} + +#define CHK_IQ_PRIO (1 << 3) /* Bit#3 is check IQ Prio */ + +/* Return flags with the in_skb_tag and chk_iq_prio set */ +static inline uint32_t _set_in_skb_n_chk_iq_prio_tag_(uint32_t flags) +{ + return (flags | FKB_IN_SKB | CHK_IQ_PRIO); +} + +/* Return flags with the chk_iq_prio set */ +static inline uint32_t _set_chk_iq_prio_tag_(uint32_t flags) +{ + return (flags | CHK_IQ_PRIO); +} + +/* Fetch the chk_iq_prio tag in flags */ +static inline uint32_t _get_chk_iq_prio_tag_(uint32_t flags) +{ + return (flags & CHK_IQ_PRIO); +} + +/* Determine whether the chk_iq_prio tag is set in flags */ +static inline uint32_t _is_chk_iq_prio_tag_(uint32_t flags) +{ + return ( _get_chk_iq_prio_tag_(flags) ? 1 : 0 ); +} + + +/* + *------------------------------------------------------------------------------ + * APIs to convert between a real kernel pointer and a dirty pointer. + *------------------------------------------------------------------------------ + */ + +#define FKB_DPTR_TAG (1 << 0) /* Bit#0 is dptr_tag */ + +/* Test whether a pointer is a dirty pointer type */ +static inline uint32_t is_dptr_tag_(uint8_t * ptr) +{ + return ( ( (uint32_t) ((uintptr_t)ptr & FKB_DPTR_TAG) ) ? 1 : 0); +} + +/* Encode a real kernel pointer to a dirty pointer type */ +static inline uint8_t * _to_dptr_from_kptr_(uint8_t * kernel_ptr) +{ + if((uintptr_t)(kernel_ptr) & FKB_DPTR_TAG) + kernel_ptr++; + /* Tag a kernel pointer's dirty_ptr bit, to denote a FKB dirty pointer */ + return ( (uint8_t*) ((uintptr_t)(kernel_ptr) | FKB_DPTR_TAG) ); +} + +/* Decode a dirty pointer type into a real kernel pointer */ +static inline uint8_t * _to_kptr_from_dptr_(uint8_t * dirty_ptr) +{ + FKB_AUDIT( + if ( dirty_ptr && !is_dptr_tag_(dirty_ptr) ) + printk("FKB ASSERT %s !is_dptr_tag_(%lu)\n", + __FUNCTION__, (uintptr_t)dirty_ptr); ); + + /* Fetch kernel pointer from encoded FKB dirty_ptr, + by clearing dirty_ptr bit */ + return ( (uint8_t*) ((uintptr_t)(dirty_ptr) & (~FKB_DPTR_TAG)) ); +} + +#define FKB_OPTR_TAG (1<<1) /* Bit#1 other_ptr tag */ + +#define FKB_BLOG_TAG_MASK (FKB_DPTR_TAG | FKB_OPTR_TAG) + +/* Verify whether a FKB pointer is pointing to a Blog */ +#define _IS_BPTR_(fkb_ptr) \ + ( _is_kptr_(fkb_ptr) && ! ((uintptr_t)(fkb_ptr) & FKB_BLOG_TAG_MASK) ) + + +/* + *------------------------------------------------------------------------------ + * + * Types of FKB objects + * + * - A Master FKB object contains memory for the rx buffer, with a FkBuff_t + * placed at the head of the buffer. A Master FKB object may serve to + * replenish a network devices receive ring, when packet buffers are not + * promptly recycled. A Master FKB may also be used for packet replication + * where in one of the transmitted packet replicas may need a unique + * modification distinct from other replicas. In such a case, the FKB must + * be first "unshared" by a deep packet buffer copy into a Master Fkb. + * If CONFIG_BCM_NBUFF_FKB_POOL is enabled then a Free Pool of Master + * FKB objects is maintained. Master FKB may be alocated and recycled from + * this Master FKB Pool.The Master FKB Pool may also be used for + * replinishing a network device driver's rx buffer ring. + * + * - A Cloned FKB object does not contain memory for the rx buffer. + * Used by fkb_clone, to create multiple references to a packet buffer. + * Multiple references to a packet buffer may be used for packet replication. + * A FKB allocated from the FKB Cloned Pool will have master_p pointing to + * a Master FKB and the recycle_hook member set to NULL. + * + *------------------------------------------------------------------------------ + */ +typedef enum { + FkbMaster_e = 0, + FkbCloned_e = 1, + FkbMaxType_e +} FkbObject_t; + +/* + * Function : _get_master_users_ + * Description: Given a pointer to a Master FKB, fetch the users count + * Caution : Does not check whether the FKB is a Master or not! + */ +static inline uint32_t _get_master_users_(FkBuff_t * fkbM_p) +{ + uint32_t users; + users = atomic_read(&fkbM_p->users); + + FKB_AUDIT( + if ( users == 0 ) + printk("FKB ASSERT cpu<%u> %s(%p) users == 0, recycle<%pS>\n", + smp_processor_id(), __FUNCTION__, + fkbM_p, fkbM_p->recycle_hook); ); + return users; +} + +/* + * Function : _is_fkb_cloned_pool_ + * Description: Test whether an "allocated" FKB is from the FKB Cloned Pool. + */ +static inline uint32_t _is_fkb_cloned_pool_(FkBuff_t * fkb_p) +{ + if ( _is_kptr_(fkb_p->master_p) + && (fkb_p->recycle_hook == (RecycleFuncP)NULL) ) + { + FKB_AUDIT( + /* ASSERT if the FKB is actually linked in a FKB pool */ + if ( _is_kptr_(fkb_p->master_p->list) ) + { + printk("FKB ASSERT cpu<%u> %s :" + " _is_kptr_((%p)->%p->%p)" + " master<%p>.recycle<%pS>\n", + smp_processor_id(), __FUNCTION__, fkb_p, + fkb_p->master_p, fkb_p->master_p->list, + fkb_p->master_p, + fkb_p->master_p->recycle_hook); + } + /* ASSERT that Master FKB users count is greater than 0 */ + if ( _get_master_users_(fkb_p->master_p) == 0 ) + { + printk("FKB ASSERT cpu<%u> %s :" + " _get_master_users_(%p->%p) == 0\n", + smp_processor_id(), __FUNCTION__, + fkb_p, fkb_p->master_p); + return 0; + } ); + + return 1; /* Allocated FKB is from the FKB Cloned Pool */ + } + else + return 0; +} + +/* + * Function : _get_fkb_users_ + * Description: Given a pointer to a FKB (Master or Cloned), fetch users count + */ +static inline uint32_t _get_fkb_users_(FkBuff_t * fkb_p) +{ + if ( _is_kptr_(fkb_p->master_p) ) /* Cloned FKB */ + { + FKB_AUDIT( + if ( !_is_fkb_cloned_pool_(fkb_p) ) /* double check Cloned FKB */ + { + printk("FKB ASSERT cpu<%u> %s :" + " !_is_fkb_cloned_pool_(%p)" + " master<%p>.recycle<%pS>\n", + smp_processor_id(), __FUNCTION__, + fkb_p, fkb_p->master_p, + fkb_p->master_p->recycle_hook); + return 0; + } ); + + return _get_master_users_(fkb_p->master_p); + } + else /* Master FKB */ + return _get_master_users_(fkb_p); +} + +/* + * Function : _get_fkb_master_ptr_ + * Description: Fetch the pointer to the Master FKB. + */ +static inline FkBuff_t * _get_fkb_master_ptr_(FkBuff_t * fkb_p) +{ + if ( _is_kptr_(fkb_p->master_p) ) /* Cloned FKB */ + { + FKB_AUDIT( + if ( !_is_fkb_cloned_pool_(fkb_p) ) /* double check Cloned FKB */ + { + printk("FKB ASSERT cpu<%u> %s " + " !_is_fkb_cloned_pool_(%p)" + " master<%p>.recycle<%pS>\n", + smp_processor_id(), __FUNCTION__, + fkb_p, fkb_p->master_p, + fkb_p->master_p->recycle_hook); + return FKB_NULL; + } ); + + return fkb_p->master_p; + } + else /* Master FKB */ + { + FKB_AUDIT( + if ( _get_master_users_(fkb_p) == 0 ) /* assert Master FKB users */ + { + printk("FKB ASSERT cpu<%u> %s " + " _get_master_users_(%p) == 0\n", + smp_processor_id(), __FUNCTION__, fkb_p); + return FKB_NULL; + } ); + + return fkb_p; + } +} + +/* + *------------------------------------------------------------------------------ + * Placement of a FKB object in the Rx DMA buffer: + * + * RX DMA Buffer: |----- FKB ----|--- reserve headroom ---|---...... + * ^ ^ ^ + * pFkb pHead pData + * pBuf + *------------------------------------------------------------------------------ + */ +#define PFKBUFF_PHEAD_OFFSET sizeof(FkBuff_t) +#define PFKBUFF_TO_PHEAD(pFkb) ((uint8_t*)((FkBuff_t*)(pFkb) + 1)) +#define PHEAD_TO_PFKBUFF(pHead) \ + (FkBuff_t *)((uint8_t*)(pHead)-PFKBUFF_PHEAD_OFFSET) + +#define PDATA_TO_PFKBUFF(pData,headroom) \ + (FkBuff_t *)((uint8_t*)(pData)-(headroom)-PFKBUFF_PHEAD_OFFSET) +#define PFKBUFF_TO_PDATA(pFkb,headroom) \ + (uint8_t*)((uint8_t*)(pFkb) + PFKBUFF_PHEAD_OFFSET + (headroom)) + + +#define NBUFF_ALIGN_MASK_8 0x07 +pNBuff_t nbuff_align_data(pNBuff_t pNBuff, uint8_t **data_pp, + uint32_t len, unsigned long alignMask); + +/* + *------------------------------------------------------------------------------ + * FKB Functional Interfaces + *------------------------------------------------------------------------------ + */ + +/* + * Function : fkb_in_skb_test + * Description: Verifies that the layout of SKB member fields corresponding to + * a FKB have the same layout. This allows a FKB to be passed via + * a SKB. + */ + +extern int fkb_in_skb_test( int fkb_in_skb_offset, + int list_offset, int blog_p_offset, + int data_offset, int len_offset, int mark_offset, + int priority_offset, int recycle_hook_offset, + int recycle_context_offset ); + +/* + * Global FKB Subsystem Constructor + * fkb_construct() validates that the layout of fkbuff members in sk_buff + * is the same. An sk_buff contains an fkbuff and permits a quick translation + * to and from a fkbuff. It also preallocates the pools of FKBs. + */ +extern int fkb_construct(int fkb_in_skb_offset); + +/* + * Function : fkb_stats + * Description: Report FKB Pool statistics, see CC_CONFIG_FKB_STATS + */ +extern void fkb_stats(void); + +/* + * Function : fkb_alloc + * Description: Allocate a Cloned/Master FKB object from preallocated pool + */ +extern FkBuff_t * fkb_alloc( FkbObject_t object ); + +/* + * Function : fkb_free + * Description: Free a FKB object to its respective preallocated pool. + */ +extern void fkb_free(FkBuff_t * fkb_p); + +/* + * Function : fkb_unshare + * Description: If a FKB is pointing to a buffer with multiple references + * to this buffer, then create a copy of the buffer and return a FKB with a + * single reference to this buffer. + */ +extern FkBuff_t * fkb_unshare(FkBuff_t * fkb_p); + +/* + * Function : fkbM_borrow + * Description: Allocate a Master FKB object from the pre-allocated pool. + */ +extern FkBuff_t * fkbM_borrow(void); + +/* + * Function : fkb_set_ref + * Description: Set reference count to an FKB. + */ +static inline void _fkb_set_ref(FkBuff_t * fkb_p, const int count) +{ + atomic_long_set(&fkb_p->users, count); +} +FKB_FN( fkb_set_ref, + void fkb_set_ref(FkBuff_t * fkb_p, const int count), + _fkb_set_ref(fkb_p, count) ) + +/* + * Function : fkb_inc_ref + * Description: Increment reference count to an FKB. + */ +static inline void _fkb_inc_ref(FkBuff_t * fkb_p) +{ + atomic_long_inc(&fkb_p->users); +} +FKB_FN( fkb_inc_ref, + void fkb_inc_ref(FkBuff_t * fkb_p), + _fkb_inc_ref(fkb_p) ) + +/* + * Function : fkb_dec_ref + * Description: Decrement reference count to an FKB. + */ +static inline void _fkb_dec_ref(FkBuff_t * fkb_p) +{ + atomic_long_dec(&fkb_p->users); + /* For debug, may want to assert that users does not become negative */ +} +FKB_FN( fkb_dec_ref, + void fkb_dec_ref(FkBuff_t * fkb_p), + _fkb_dec_ref(fkb_p) ) + + +/* + * Function : fkb_preinit + * Description: A network device driver may use this function to place a + * FKB object into rx buffers, when they are created. FKB objects preceeds + * the reserved headroom. + */ +static inline void fkb_preinit(uint8_t * pBuf, RecycleFuncP recycle_hook, + unsigned long recycle_context) +{ + FkBuff_t *fkb_p = (FkBuff_t *)pBuf; + fkb_p->recycle_hook = recycle_hook; /* never modified */ + fkb_p->recycle_context = recycle_context; /* never modified */ + + fkb_p->ptr = NULL; /* resets dirty_p, blog_p */ + fkb_p->data = NULL; + fkb_p->len_word = 0; + fkb_p->mark = 0; + fkb_p->priority = 0; + fkb_set_ref(fkb_p, 0); +} + +/* + * Function : fkb_init + * Description: Initialize the FKB context for a received packet. Invoked by a + * network device on extract the packet from a buffer descriptor and associating + * a FKB context to the received packet. + */ +static inline FkBuff_t * _fkb_init(uint8_t * pBuf, uint32_t headroom, + uint8_t * pData, uint32_t len) +{ + FkBuff_t * fkb_p = PDATA_TO_PFKBUFF(pBuf, headroom); + fkb_dbg( 1, "fkb_p<%px> pBuf<%px> headroom<%u> pData<%px> len<%d>", + fkb_p, pBuf, (int)headroom, pData, len ); + +#if defined(CC_FKB_HEADROOM_AUDIT) + if ( headroom < BCM_PKT_HEADROOM ) + printk("NBUFF: Insufficient headroom <%u>, need <%u> %-10s\n", + headroom, BCM_PKT_HEADROOM, __FUNCTION__); +#endif + + fkb_p->data = pData; + fkb_p->len_word = 0;/*clear flags */ + fkb_p->len = len; + fkb_p->ptr = (void*)NULL; /* resets dirty_p, blog_p */ + fkb_p->mark = 0; + fkb_p->priority = 0; + + fkb_set_ref( fkb_p, 1 ); + + return fkb_p; +} +FKB_FN( fkb_init, + FkBuff_t * fkb_init(uint8_t * pBuf, uint32_t headroom, + uint8_t * pData, uint32_t len), + return _fkb_init(pBuf, headroom, pData, len) ) + +/* + * Function : fkb_qinit + * Description: Same as fkb_init, with the exception that a recycle queue + * context is associated with the FKB, each time the packet is receieved. + */ +static inline FkBuff_t * _fkb_qinit(uint8_t * pBuf, uint32_t headroom, + uint8_t * pData, uint32_t len, unsigned long qcontext) +{ + FkBuff_t * fkb_p = PDATA_TO_PFKBUFF(pBuf, headroom); + fkb_dbg(1, "fkb_p<%p> qcontext<%lx>", fkb_p, qcontext ); + fkb_p->recycle_context = qcontext; + + return _fkb_init(pBuf, headroom, pData, len); +} +FKB_FN( fkb_qinit, + FkBuff_t * fkb_qinit(uint8_t * pBuf, uint32_t headroom, + uint8_t * pData, uint32_t len, unsigned long qcontext), + return _fkb_qinit(pBuf, headroom, pData, len, qcontext) ) + +/* + * Function : fkb_release + * Description: Release any associated blog and set ref count to 0. A fkb + * may be released multiple times (not decrement reference count). + */ +static inline void _fkb_release(FkBuff_t * fkb_p) +{ + fkb_dbg(1, "fkb_p<%p> fkb_p->blog_p<%px>", fkb_p, fkb_p->blog_p ); +#if defined(CONFIG_BLOG) + if ( _IS_BPTR_( fkb_p->blog_p ) ) + blog_put(fkb_p->blog_p); +#endif + fkb_p->ptr = (void*)NULL; /* reset dirty_p, blog_p */ + + fkb_set_ref( fkb_p, 0 ); /* fkb_release may be invoked multiple times */ +} +FKB_FN( fkb_release, + void fkb_release(FkBuff_t * fkb_p), + _fkb_release(fkb_p) ) + +/* + * Function : fkb_headroom + * Description: Determine available headroom for the packet in the buffer. + */ +static inline int _fkb_headroom(const FkBuff_t *fkb_p) +{ + return (int)( (uintptr_t)(fkb_p->data) - (uintptr_t)(fkb_p+1) ); +} +FKB_FN( fkb_headroom, + int fkb_headroom(const FkBuff_t *fkb_p), + return _fkb_headroom(fkb_p) ) + +/* + * Function : fkb_init_headroom + * Description: The available headroom the packet in the buffer at fkb_init time. + */ +static inline int _fkb_init_headroom(void) +{ + return BCM_PKT_HEADROOM; +} +FKB_FN( fkb_init_headroom, + int fkb_init_headroom(void), + return _fkb_init_headroom() ) + + +/* + * Function : fkb_push + * Description: Prepare space for data at head of the packet buffer. + */ +static inline uint8_t * _fkb_push(FkBuff_t * fkb_p, uint32_t len) +{ + fkb_p->len += len; + fkb_p->data -= len; + return fkb_p->data; +} +FKB_FN( fkb_push, + uint8_t * fkb_push(FkBuff_t * fkb_p, uint32_t len), + return _fkb_push(fkb_p, len) ) + +/* + * Function : fkb_pull + * Description: Delete data from the head of packet buffer. + */ +static inline uint8_t * _fkb_pull(FkBuff_t * fkb_p, uint32_t len) +{ + fkb_p->len -= len; + fkb_p->data += len; + return fkb_p->data; +} +FKB_FN( fkb_pull, + uint8_t * fkb_pull(FkBuff_t * fkb_p, uint32_t len), + return _fkb_pull(fkb_p, len) ) + +/* + * Function : fkb_put + * Description: Prepare space for data at tail of the packet buffer. + */ +static inline uint8_t * _fkb_put(FkBuff_t * fkb_p, uint32_t len) +{ + uint8_t * tail_p = fkb_p->data + fkb_p->len; + fkb_p->len += len; + return tail_p; +} +FKB_FN( fkb_put, + uint8_t * fkb_put(FkBuff_t * fkb_p, uint32_t len), + return _fkb_put(fkb_p, len) ) + +/* + * Function : fkb_pad + * Description: Pad the packet by requested number of bytes. + */ +static inline uint32_t _fkb_pad(FkBuff_t * fkb_p, uint32_t padding) +{ + memset((uint8_t *)(fkb_p->data + fkb_p->len), 0, padding); + fkb_p->len += padding; + return fkb_p->len; +} +FKB_FN( fkb_pad, + uint32_t fkb_pad(FkBuff_t * fkb_p, uint32_t padding), + return _fkb_pad(fkb_p, padding) ) + +/* + * Function : fkb_len + * Description: Determine the length of the packet. + */ +static inline uint32_t _fkb_len(FkBuff_t * fkb_p) +{ + return fkb_p->len; +} +FKB_FN( fkb_len, + uint32_t fkb_len(FkBuff_t * fkb_p), + return _fkb_len(fkb_p) ) + +/* + * Function : fkb_data + * Description: Fetch the start of the packet. + */ +static inline uint8_t * _fkb_data(FkBuff_t * fkb_p) +{ + return fkb_p->data; +} +FKB_FN( fkb_data, + uint8_t * fkb_data(FkBuff_t * fkb_p), + return _fkb_data(fkb_p) ) + +#if defined(CONFIG_BLOG) +/* + * Function : fkb_blog + * Description: Fetch the associated blog. + */ +static inline struct blog_t * _fkb_blog(FkBuff_t * fkb_p) +{ + return fkb_p->blog_p; +} +FKB_FN( fkb_blog, + struct blog_t * fkb_blog(FkBuff_t * fkb_p), + return _fkb_blog(fkb_p) ) +#endif + +/* + * Function : fkb_clone + * Description: Allocate a FKB from the Cloned Pool and make it reference the + * same packet. fkbInSkb case allocates a new master FKB and copy the data + * (basically a FKB copy). + * + */ +static inline FkBuff_t * _fkb_clone(FkBuff_t * fkb_p) +{ + FkBuff_t *fkbM_p; + + FKB_AUDIT( + if ( smp_processor_id() ) + printk("FKB ASSERT %s not supported on CP 1\n", __FUNCTION__); ); + + /* Fetch a pointer to the Master FKB */ + fkbM_p = _get_fkb_master_ptr_( fkb_p ); + + if ( !is_dptr_tag_(fkbM_p->dirty_p ) && _is_in_skb_tag_(fkbM_p->ptr, fkbM_p->flags) ) + { + /* FKB Alloc and copy */ + fkbM_p = fkb_alloc( FkbMaster_e ); + if (fkbM_p == FKB_NULL) + { + fkb_dbg(1, "fkb_clone FKB fkb_alloc failure"); + return FKB_NULL; + } + fkb_set_ref(fkbM_p, 1); + + fkbM_p->data = PFKBUFF_TO_PDATA(fkbM_p, BCM_PKT_HEADROOM); + + fkbM_p->len_word = fkb_p->len_word; + fkbM_p->mark = fkb_p->mark; + fkbM_p->priority = fkb_p->priority; + fkbM_p->dirty_p = _to_dptr_from_kptr_(fkbM_p->data + fkbM_p->len); + + memcpy(fkbM_p->data, fkb_p->data, fkb_p->len); + + fkb_dbg(1, "fkbM_p<%p> ---> fkb_p<%p>", fkbM_p, fkb_p ); + + return fkbM_p; + } + else + { + FkBuff_t *fkbC_p = fkb_alloc( FkbCloned_e ); /* Allocate FKB from Cloned pool */ + + if ( unlikely(fkbC_p != FKB_NULL) ) + { + fkb_inc_ref( fkbM_p ); + fkbC_p->master_p = fkbM_p; + fkbC_p->ptr = fkbM_p->ptr; + + fkbC_p->data = fkbM_p->data; + fkbC_p->len_word = fkbM_p->len_word; + fkbC_p->mark = fkbM_p->mark; + fkbC_p->priority = fkbM_p->priority; + } + + fkb_dbg(1, "fkbC_p<%p> ---> fkbM_p<%p>", fkbC_p, fkbM_p ); + + return fkbC_p; /* May be null */ + } +} +FKB_FN( fkb_clone, + FkBuff_t * fkb_clone(FkBuff_t * fkbM_p), + return _fkb_clone(fkbM_p) ) + +extern void fkb_flush(FkBuff_t * fkb_p, uint8_t * data_p, int len, int cache_op); + +/* + *------------------------------------------------------------------------------ + * Virtual accessors to common members of network kernel buffer + *------------------------------------------------------------------------------ + */ + +/* __BUILD_NBUFF_SET_ACCESSOR: generates function nbuff_set_MEMBER() */ +#define __BUILD_NBUFF_SET_ACCESSOR( TYPE, MEMBER ) \ +static inline void nbuff_set_##MEMBER(pNBuff_t pNBuff, TYPE MEMBER) \ +{ \ + void * pBuf = PNBUFF_2_PBUF(pNBuff); \ + if ( IS_SKBUFF_PTR(pNBuff) ) \ + ((struct sk_buff *)pBuf)->MEMBER = MEMBER; \ + /* else if IS_FPBUFF_PTR, else if IS_TGBUFF_PTR */ \ + else \ + ((FkBuff_t *)pBuf)->MEMBER = MEMBER; \ +} + +/* __BUILD_NBUFF_GET_ACCESSOR: generates function nbuff_get_MEMBER() */ +#define __BUILD_NBUFF_GET_ACCESSOR( TYPE, MEMBER ) \ +static inline TYPE nbuff_get_##MEMBER(pNBuff_t pNBuff) \ +{ \ + void * pBuf = PNBUFF_2_PBUF(pNBuff); \ + if ( IS_SKBUFF_PTR(pNBuff) ) \ + return (TYPE)(((struct sk_buff *)pBuf)->MEMBER); \ + /* else if IS_FPBUFF_PTR, else if IS_TGBUFF_PTR */ \ + else \ + return (TYPE)(((FkBuff_t *)pBuf)->MEMBER); \ +} + +/* + * Common set/get accessor of base network buffer fields: + * nbuff_set_data(), nbuff_set_len(), nbuff_set_mark(), nbuff_set_priority() + * nbuff_get_data(), nbuff_get_len(), nbuff_get_mark(), nbuff_get_priority() + */ +__BUILD_NBUFF_SET_ACCESSOR(uint8_t *, data) +__BUILD_NBUFF_SET_ACCESSOR(uint32_t, len) +__BUILD_NBUFF_SET_ACCESSOR(uint32_t, mark) /* Custom network buffer arg1 */ +__BUILD_NBUFF_SET_ACCESSOR(void *, queue) /* Custom network buffer arg1 */ +__BUILD_NBUFF_SET_ACCESSOR(uint32_t, priority) /* Custom network buffer arg2 */ + +__BUILD_NBUFF_GET_ACCESSOR(uint8_t *, data) +__BUILD_NBUFF_GET_ACCESSOR(uint32_t, len) +__BUILD_NBUFF_GET_ACCESSOR(uint32_t, mark) /* Custom network buffer arg1 */ +__BUILD_NBUFF_GET_ACCESSOR(void *, queue) /* Custom network buffer arg1 */ +__BUILD_NBUFF_GET_ACCESSOR(uint32_t, priority) /* Custom network buffer arg2 */ + +/* + * Function : nbuff_get_context + * Description: Extracts the data and len fields from a pNBuff_t. + */ +static inline void * nbuff_get_context(pNBuff_t pNBuff, + uint8_t ** data_p, uint32_t *len_p) +{ + void * pBuf = PNBUFF_2_PBUF(pNBuff); + if ( pBuf == (void*) NULL ) + return pBuf; + if ( IS_SKBUFF_PTR(pNBuff) ) + { + *data_p = ((struct sk_buff *)pBuf)->data; + *len_p = ((struct sk_buff *)pBuf)->len; + } + else + { + *data_p = ((FkBuff_t *)pBuf)->data; + *len_p = ((FkBuff_t *)pBuf)->len; + } + fkb_dbg(1, "pNBuff<%p> pBuf<%p> data_p<%p>", + pNBuff, pBuf, *data_p ); + return pBuf; +} + +/* + * Function : nbuff_get_params + * Description: Extracts the data, len, mark and priority field from a network + * buffer. + */ +static inline void * nbuff_get_params(pNBuff_t pNBuff, + uint8_t ** data_p, uint32_t *len_p, + uint32_t * mark_p, uint32_t *priority_p) +{ + void * pBuf = PNBUFF_2_PBUF(pNBuff); + if ( pBuf == (void*) NULL ) + return pBuf; + if ( IS_SKBUFF_PTR(pNBuff) ) + { + *data_p = ((struct sk_buff *)pBuf)->data; + *len_p = ((struct sk_buff *)pBuf)->len; + *mark_p = ((struct sk_buff *)pBuf)->mark; + *priority_p = ((struct sk_buff *)pBuf)->priority; + } + else + { + *data_p = ((FkBuff_t *)pBuf)->data; + *len_p = ((FkBuff_t *)pBuf)->len; + *mark_p = ((FkBuff_t *)pBuf)->mark; + *priority_p = ((FkBuff_t *)pBuf)->priority; + } + fkb_dbg(1, "pNBuff<%px> pBuf<%px> data_p<%px>", + pNBuff, pBuf, *data_p ); + return pBuf; +} + +/* adds recycle flags/context to nbuff_get_params used in impl4 enet */ +/* + * Function : nbuff_get_params_ext + * Description: Extracts the data, len, mark, priority and + * recycle flags/context field from a network buffer. + */ +static inline void * nbuff_get_params_ext(pNBuff_t pNBuff, uint8_t **data_p, + uint32_t *len_p, uint32_t *mark_p, + uint32_t *priority_p, + uint32_t *rflags_p) +{ + void * pBuf = PNBUFF_2_PBUF(pNBuff); + if ( pBuf == (void*) NULL ) + return pBuf; + if ( IS_SKBUFF_PTR(pNBuff) ) + { + *data_p = ((struct sk_buff *)pBuf)->data; + *len_p = ((struct sk_buff *)pBuf)->len; + *mark_p = ((struct sk_buff *)pBuf)->mark; + *priority_p = ((struct sk_buff *)pBuf)->priority; +#if defined(CONFIG_BLOG) + *rflags_p = ((struct sk_buff *)pBuf)->recycle_flags; +#endif + } + else + { + *data_p = ((FkBuff_t *)pBuf)->data; + *len_p = ((FkBuff_t *)pBuf)->len; + *mark_p = ((FkBuff_t *)pBuf)->mark; + *priority_p = ((FkBuff_t *)pBuf)->priority; +#if defined(CONFIG_BLOG) + *rflags_p = ((FkBuff_t *)pBuf)->recycle_context; +#endif + } + fkb_dbg(1, "pNBuff<%px> pBuf<%px> data_p<%px>", + pNBuff, pBuf, *data_p ); + return pBuf; +} + +/* + *------------------------------------------------------------------------------ + * Virtual common functional apis of a network kernel buffer + *------------------------------------------------------------------------------ + */ + +/* + * Function : nbuff_push + * Description: Make space at the start of a network buffer. + * CAUTION : In the case of a FKB, no check for headroom is done. + */ +static inline uint8_t * nbuff_push(pNBuff_t pNBuff, uint32_t len) +{ + uint8_t * data; + void * pBuf = PNBUFF_2_PBUF(pNBuff); + if ( IS_SKBUFF_PTR(pNBuff) ) + data = skb_push(((struct sk_buff *)pBuf), len); + /* else if IS_FPBUFF_PTR, else if IS_TGBUFF_PTR */ + else + data = fkb_push((FkBuff_t*)pBuf, len); + fkb_dbg(1, "pNBuff<%px> pBuf<%px> data<%px> len<%u>", + pNBuff, pBuf, data, len ); + return data; +} + +/* + * Function : nbuff_pull + * Description: Delete data from start of a network buffer. + */ +static inline uint8_t * nbuff_pull(pNBuff_t pNBuff, uint32_t len) +{ + uint8_t * data; + void * pBuf = PNBUFF_2_PBUF(pNBuff); + if ( IS_SKBUFF_PTR(pNBuff) ) + data = skb_pull(((struct sk_buff *)pBuf), len); + /* else if IS_FPBUFF_PTR, else if IS_TGBUFF_PTR */ + else + data = fkb_pull((FkBuff_t *)pBuf, len); + fkb_dbg(1, "pNBuff<%px> pBuf<%px> data<%px> len<%u>", + pNBuff, pBuf, data, len ); + return data; +} + +/* + * Function : nbuff_put + * Description: Make space at the tail of a network buffer. + * CAUTION: In the case of a FKB, no check for tailroom is done. + */ +static inline uint8_t * nbuff_put(pNBuff_t pNBuff, uint32_t len) +{ + uint8_t * tail; + void * pBuf = PNBUFF_2_PBUF(pNBuff); + if ( IS_SKBUFF_PTR(pNBuff) ) + tail = skb_put(((struct sk_buff *)pBuf), len); + /* else if IS_FPBUFF_PTR, else if IS_TGBUFF_PTR */ + else + tail = fkb_put((FkBuff_t *)pBuf, len); + fkb_dbg(1, "pNBuff<%px> pBuf<%px> tail<%px> len<%u>", + pNBuff, pBuf, tail, len ); + return tail; +} + +#ifdef CONFIG_BCM_SKB_FREE_THREAD +extern void dev_kfree_skb_thread(struct sk_buff *skb); +#endif +extern void nbuff_free_ex(pNBuff_t pNBuff, int in_thread); +extern void nbuff_free(pNBuff_t pNBuff); + +/* + * Function : nbuff_unshare + * Description: If there are more than one references to the data buffer + * associated with the network buffer, create a deep copy of the data buffer + * and return a network buffer context to it. The returned network buffer + * may be then used to modify the data packet without impacting the original + * network buffer and its data buffer. + * + * If the data packet had a single network buffer referencing it, then the + * original network buffer is returned. + */ +static inline pNBuff_t nbuff_unshare(pNBuff_t pNBuff) +{ + void * pBuf = PNBUFF_2_PBUF(pNBuff); + fkb_dbg(1, "pNBuff<%px> pBuf<%px>", pNBuff, pBuf); + if ( IS_SKBUFF_PTR(pNBuff) ) + { + struct sk_buff *skb_p; + skb_p = skb_unshare( (struct sk_buff *)pBuf, GFP_ATOMIC); + pNBuff = SKBUFF_2_PNBUFF(skb_p); + } + else + { + FkBuff_t * fkb_p; + fkb_p = fkb_unshare( (FkBuff_t *)pBuf ); + pNBuff = FKBUFF_2_PNBUFF(fkb_p); + } + + fkb_dbg(2, "<<"); + return pNBuff; +} + +/* + * Function : nbuff_invalidate_headroom + * Description: invalidate datacache lines of memory prefixing "data" pointer. + * Invalidation does not include the dcache line "data" is in. This dcache line + * must be flushed, not invalidated. + */ +static inline void nbuff_invalidate_headroom(pNBuff_t pNBuff, uint8_t * data) +{ + + /* Invalidate functions used here will round up end pointer to cache line + * boundry. That's the reason for L1_CACHE_BYTES substruction. + */ + int32_t inv_len = 0; + fkb_dbg(1, "pNBuff<%p> data<%p>", pNBuff, data); + + if ( IS_SKBUFF_PTR(pNBuff) ) + { + inv_len = skb_avail_headroom( PNBUFF_2_SKBUFF(pNBuff) ) - L1_CACHE_BYTES; + cache_invalidate_region(PNBUFF_2_SKBUFF(pNBuff)->head, data - L1_CACHE_BYTES); + } + else + { + FkBuff_t * fkb_p = (FkBuff_t *)PNBUFF_2_PBUF(pNBuff); + + if ( _is_fkb_cloned_pool_(fkb_p) ) + fkb_p = fkb_p->master_p; + + inv_len = data - PFKBUFF_TO_PHEAD(fkb_p) - L1_CACHE_BYTES; + fkb_flush(fkb_p, PFKBUFF_TO_PHEAD(fkb_p), inv_len, FKB_CACHE_INV); + } + fkb_dbg(1, " len<%d>", inv_len); + fkb_dbg(2, "<<"); +} + +extern void nbuff_flush(pNBuff_t pNBuff, uint8_t * data, int len); +extern void nbuff_flushfree(pNBuff_t pNBuff); + +/* + * Function : nbuff_xlate + * Description: Convert a FKB to a SKB. The SKB is data filled with the + * data, len, mark, priority, and recycle hook and context. + * + * Other SKB fields for SKB API manipulation are also initialized. + * SKB fields for network stack manipulation are NOT initialized. + * + * This function is typically used only in a network device drivers' hard + * start xmit function handler. A hard start xmit function handler may receive + * a network buffer of a FKB type and may not wish to rework the implementation + * to use nbuff APIs. In such an event, a nbuff may be translated to a skbuff. + */ +struct sk_buff * fkb_xlate(FkBuff_t * fkb_p); +static inline struct sk_buff * nbuff_xlate( pNBuff_t pNBuff ) +{ + void * pBuf = PNBUFF_2_PBUF(pNBuff); + fkb_dbg(1, "pNBuff<%px> pBuf<%px>", pNBuff, pBuf); + + if ( IS_SKBUFF_PTR(pNBuff) ) + return (struct sk_buff *)pBuf; + /* else if IS_FPBUFF_PTR, else if IS_TGBUFF_PTR */ + else + return fkb_xlate( (FkBuff_t *)pBuf ); +} + + +/* Miscellaneous helper routines */ +static inline void u16cpy( void * dst_p, const void * src_p, uint32_t bytes ) +{ + uint16_t * dst16_p = (uint16_t*)dst_p; + uint16_t * src16_p = (uint16_t*)src_p; + do { // assuming: (bytes % sizeof(uint16_t) == 0 !!! + *dst16_p++ = *src16_p++; + } while ( bytes -= sizeof(uint16_t) ); +} + +static inline void u16datacpy( void * dst_p, const void * src_p, uint32_t bytes ) +{ + uint16_t * dst16_p = (uint16_t*)dst_p; + uint16_t * src16_p = (uint16_t*)src_p; + do { // assuming: (bytes % sizeof(uint16_t) == 0 !!! + *dst16_p++ = htons (*src16_p++); + } while ( bytes -= sizeof(uint16_t) ); +} + +static inline int u16cmp( void * dst_p, const void * src_p, + uint32_t bytes ) +{ + uint16_t * dst16_p = (uint16_t*)dst_p; + uint16_t * src16_p = (uint16_t*)src_p; + do { // assuming: (bytes % sizeof(uint16_t) == 0 !!! + if ( *dst16_p++ != *src16_p++ ) + return -1; + } while ( bytes -= sizeof(uint16_t) ); + + return 0; +} + +static inline int nbuff_pad(pNBuff_t pNBuff, int padLen) +{ + if ( IS_SKBUFF_PTR(pNBuff) ) + { + int ret = skb_put_padto((struct sk_buff *)pNBuff, padLen + ((struct sk_buff *)pNBuff)->len); + if (ret) + printk(KERN_ERR "nbuff_pad() skb_put_padto err=%d!!\n", ret); + return ret; + } + else + { + fkb_pad(PNBUFF_2_FKBUFF(pNBuff), padLen); + } + return 0; +} + +#ifdef DUMP_DATA +/* dumpHexData dump out the hex base binary data */ +static inline void dumpHexData1(uint8_t *pHead, uint32_t len) +{ + uint32_t i; + uint8_t *c = pHead; + for (i = 0; i < len; ++i) { + if (i % 16 == 0) + printk("\n"); + printk("0x%02X, ", *c++); + } + printk("\n"); +} + +static inline void dump_pkt(const char * fname, uint8_t * pBuf, uint32_t len) +{ + //int dump_len = ( len < 64) ? len : 64; + int dump_len = len ; + printk("%s: data<0x%lu len<%u>", fname, (uintptr_t)pBuf, len); + dumpHexData1(pBuf, dump_len); + cache_flush_len((void*)pBuf, dump_len); +} +#define DUMP_PKT(pBuf,len) dump_pkt(__FUNCTION__, (pBuf), (len)) +#else /* !defined(DUMP_DATA) */ +#define DUMP_PKT(pBuf,len) do {} while(0) +#endif + +#endif /* defined(__NBUFF_H_INCLUDED__) */ diff --git a/include/linux/nbuff_types.h b/include/linux/nbuff_types.h new file mode 100644 index 0000000000000000000000000000000000000000..672f79c6189b21e94ac72e0ff4f6cd55f8890994 --- /dev/null +++ b/include/linux/nbuff_types.h @@ -0,0 +1,68 @@ +#ifndef __NBUFF_TYPES_H_INCLUDED__ +#define __NBUFF_TYPES_H_INCLUDED__ + +/* +<:copyright-BRCM:2013:DUAL/GPL:standard + + Copyright (c) 2013 Broadcom + All Rights Reserved + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + +/* + ******************************************************************************* + * + * File Name : nbuff_types.h + * Description: Simple nbuff type defines. + * + ******************************************************************************* */ + +#define MUST_BE_ZERO 0 + +/* virtual network buffer pointer to SKB|FPB|TGB|FKB */ +typedef void * pNBuff_t; +#define PNBUFF_NULL ((pNBuff_t)NULL) + +typedef enum NBuffPtrType +{ + SKBUFF_PTR = MUST_BE_ZERO, /* Default Linux networking socket buffer */ + FPBUFF_PTR, /* Experimental BRCM IuDMA freepool buffer*/ + TGBUFF_PTR, /* LAB Traffic generated network buffer */ + FKBUFF_PTR, /* Lightweight fast kernel network buffer */ + /* Do not add new ptr types */ +} NBuffPtrType_t; + + /* 2lsbits in pointer encode NbuffType_t */ +#define NBUFF_TYPE_MASK 0x3ul +#define NBUFF_PTR_MASK (~NBUFF_TYPE_MASK) +#define NBUFF_PTR_TYPE(pNBuff) ((uintptr_t)(pNBuff) & NBUFF_TYPE_MASK) + + +#define IS_SKBUFF_PTR(pNBuff) ( NBUFF_PTR_TYPE(pNBuff) == SKBUFF_PTR ) +#define IS_FPBUFF_PTR(pNBuff) ( NBUFF_PTR_TYPE(pNBuff) == FPBUFF_PTR ) +#define IS_TGBUFF_PTR(pNBuff) ( NBUFF_PTR_TYPE(pNBuff) == TGBUFF_PTR ) +#define IS_FKBUFF_PTR(pNBuff) ( NBUFF_PTR_TYPE(pNBuff) == FKBUFF_PTR ) + + +#endif /* defined(__NBUFF_TYPES_H_INCLUDED__) */ diff --git a/include/linux/netfilter/bcm_nfnetlink_conntrack.h b/include/linux/netfilter/bcm_nfnetlink_conntrack.h new file mode 100644 index 0000000000000000000000000000000000000000..a1051478648a78adbedfef0112f4a39c46fbd071 --- /dev/null +++ b/include/linux/netfilter/bcm_nfnetlink_conntrack.h @@ -0,0 +1,9 @@ +#ifndef _BCM_NFNETLINK_CONNTRACK_H +#define _BCM_NFNETLINK_CONNTRACK_H + +extern int bcm_ctnetlink_size(const struct nf_conn *ct); +extern int bcm_ctnetlink_dump(struct sk_buff *skb, const struct nf_conn *ct); +extern int bcm_ctnetlink_change(struct nf_conn *ct, + const struct nlattr * const cda[]); + +#endif /* _BCM_NFNETLINK_CONNTRACK_H */ diff --git a/include/linux/netfilter/nf_conntrack_ipsec.h b/include/linux/netfilter/nf_conntrack_ipsec.h new file mode 100644 index 0000000000000000000000000000000000000000..4a709a8fb94afbf9af69f423d7e5735c12130bc5 --- /dev/null +++ b/include/linux/netfilter/nf_conntrack_ipsec.h @@ -0,0 +1,43 @@ +/* IPSEC constants and structs */ +#ifndef _NF_CONNTRACK_IPSEC_H +#define _NF_CONNTRACK_IPSEC_H + +#include <linux/netfilter/nf_conntrack_common.h> + +/* conntrack private data */ +struct nf_ct_ipsec_master +{ + __be32 initcookie; /* initcookie of ISAKMP */ + __be32 lan_ip; /* LAN IP */ +}; + +struct nf_nat_ipsec +{ + __be32 lan_ip; /* LAN IP */ +}; + +#ifdef __KERNEL__ + +#define IPSEC_PORT 500 +#define MAX_VPN_CONNECTION 8 + +struct isakmp_pkt_hdr +{ + __be32 initcookie; +}; + + +/* crap needed for nf_conntrack_compat.h */ +struct nf_conn; +struct nf_conntrack_expect; + +extern int +(*nf_nat_ipsec_hook_outbound)(struct sk_buff *skb, + struct nf_conn *ct, enum ip_conntrack_info ctinfo); + +extern int +(*nf_nat_ipsec_hook_inbound)(struct sk_buff *skb, struct nf_conn *ct, + enum ip_conntrack_info ctinfo, __be32 lan_ip); + +#endif /* __KERNEL__ */ +#endif /* _NF_CONNTRACK_IPSEC_H */ diff --git a/include/linux/netfilter/nf_conntrack_proto_esp.h b/include/linux/netfilter/nf_conntrack_proto_esp.h new file mode 100644 index 0000000000000000000000000000000000000000..2717a52cc504f7f266b28ce6df3b826fb2ca9905 --- /dev/null +++ b/include/linux/netfilter/nf_conntrack_proto_esp.h @@ -0,0 +1,23 @@ +#if defined(CONFIG_BCM_KF_PROTO_ESP) +#ifndef _CONNTRACK_PROTO_ESP_H +#define _CONNTRACK_PROTO_ESP_H +#include <asm/byteorder.h> + +/* ESP PROTOCOL HEADER */ + +struct esphdr { + __u32 spi; +}; + +struct nf_ct_esp { + unsigned int stream_timeout; + unsigned int timeout; +}; + +#ifdef __KERNEL__ +#include <net/netfilter/nf_conntrack_tuple.h> + +#endif /* __KERNEL__ */ +#endif /* _CONNTRACK_PROTO_ESP_H */ +#endif + diff --git a/include/linux/netfilter/nf_conntrack_rtsp.h b/include/linux/netfilter/nf_conntrack_rtsp.h new file mode 100644 index 0000000000000000000000000000000000000000..e087a5141f776e5d3d7bf81bd19323d6217e381c --- /dev/null +++ b/include/linux/netfilter/nf_conntrack_rtsp.h @@ -0,0 +1,91 @@ +/* +* <:copyright-BRCM:2012:DUAL/GPL:standard +* +* Copyright (c) 2012 Broadcom +* All Rights Reserved +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed +* to you under the terms of the GNU General Public License version 2 +* (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +* with the following added to such license: +* +* As a special exception, the copyright holders of this software give +* you permission to link this software with independent modules, and +* to copy and distribute the resulting executable under terms of your +* choice, provided that you also meet, for each linked independent +* module, the terms and conditions of the license of that module. +* An independent module is a module which is not derived from this +* software. The special exception does not apply to any modifications +* of the software. +* +* Not withstanding the above, under no circumstances may you combine +* this software in any way with any other Broadcom software provided +* under a license other than the GPL, without Broadcom's express prior +* written consent. +* +:> +*/ + +#ifndef _NF_CONNTRACK_RTSP_H +#define _NF_CONNTRACK_RTSP_H + +#ifdef __KERNEL__ + +/* This structure exists only once per master */ +struct nf_ct_rtsp_master { + /* The client has sent PAUSE message and not replied */ + int paused; +}; + +/* Single data channel */ +extern int (*nat_rtsp_channel_hook) (struct sk_buff *skb, + unsigned int protoff, + struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + unsigned int matchoff, + unsigned int matchlen, + struct nf_conntrack_expect *exp, + int *delta); + +/* A pair of data channels (RTP/RTCP) */ +extern int (*nat_rtsp_channel2_hook) (struct sk_buff *skb, + unsigned int protoff, + struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + unsigned int matchoff, + unsigned int matchlen, + struct nf_conntrack_expect *rtp_exp, + struct nf_conntrack_expect *rtcp_exp, + char dash, int *delta); + +/* Modify parameters like client_port in Transport for single data channel */ +extern int (*nat_rtsp_modify_port_hook) (struct sk_buff *skb, + unsigned int protoff, + struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + unsigned int matchoff, + unsigned int matchlen, + __be16 rtpport, int *delta); + +/* Modify parameters like client_port in Transport for multiple data channels*/ +extern int (*nat_rtsp_modify_port2_hook) (struct sk_buff *skb, + unsigned int protoff, + struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + unsigned int matchoff, + unsigned int matchlen, + __be16 rtpport, __be16 rtcpport, + char dash, int *delta); + +/* Modify parameters like destination in Transport */ +extern int (*nat_rtsp_modify_addr_hook) (struct sk_buff *skb, + unsigned int protoff, + struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + int matchoff, int matchlen, + int *delta); +#endif /* __KERNEL__ */ + +#endif /* _NF_CONNTRACK_RTSP_H */ + diff --git a/include/linux/tracker.h b/include/linux/tracker.h new file mode 100644 index 0000000000000000000000000000000000000000..c4cad1bca0878227366ba4ceb9785ece63f036c0 --- /dev/null +++ b/include/linux/tracker.h @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2020 Broadcom +* All Rights Reserved +* +<:label-BRCM:2020:DUAL/GPL:standard + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ +#ifndef TRACKER_H +#define TRACKER_H + +/* The tracker allows to track arbitrary pointers across the kernel lifetime. + * + * Expected usage is to sprinkle track_printf's in the interesting points of + * ptr usage. + * + * The resulting strings are accessible in the shell by catting /proc/tracker. + * + * When investigating specific badness tracker_print and tracker_find are useful + * to dump or work with this information from inside of the kernel. + */ + +/* Initialize tracker. Should be called once */ +void track_init(void); + +/* Dumps information regarding ptr to dmesg */ +void tracker_print(void *ptr); + +/* Looks for pointer ptr_any. If found, tracker_find calls cb callback for each recorded state. + * In addition to state the callback gets arbitrary ctx passed by the caller. + * + * This function is useful to analyse the pointer states during runtime. Here is example + * diff which helped us track freeing non-allocated pointer in linux kernel: + * + * +static void seen_alloc(void *ctx, const char *st) { + * + int *alloced = ctx; + * + + * + if (strncmp(st, "header_alloc", strlen("header_alloc")) == 0) + * + *alloced = 1; + * +} + * + + * static void drop_sysctl_table(struct ctl_table_header *header) + * { + * struct ctl_dir *parent = header->parent; + * + int alloced = 0; + * + * if (--header->nreg) + * return; + * + * + tracker_find(header, seen_alloc, &alloced); + * + if (!alloced) { + * + printk("boriss: non alloced header %px\n", header); + * + WARN_ON(1); + * + } + * + */ +void tracker_find(void *ptr_any, void (*cb)(void *ctx, const char *st), void *ctx); + +/* printf into new state string attached to the pointer ptr. The resulting string will + * be dumped by tracker_print and passed to the callback in tracker_find. + */ +void track_printf(void *ptr, const char *fmt, ...); + +#endif /* TRACKER_H */ diff --git a/include/linux/vlanctl_bind.h b/include/linux/vlanctl_bind.h new file mode 100755 index 0000000000000000000000000000000000000000..20a1ad2197a92e1031249659e27efd2236439b65 --- /dev/null +++ b/include/linux/vlanctl_bind.h @@ -0,0 +1,123 @@ +/* +* Copyright (c) 2003-2014 Broadcom Corporation +* All Rights Reserved +* +<:label-BRCM:2014:DUAL/GPL:standard + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + + +#ifndef _VLANCTL_BIND_ +#define _VLANCTL_BIND_ + +typedef enum { + VLANCTL_BIND_CLIENT_UNKNOWN, +#if defined(CONFIG_BCM_RDPA) || defined(CONFIG_BCM_RDPA_MODULE) + VLANCTL_BIND_CLIENT_RUNNER, +#endif /* RDPA */ + VLANCTL_BIND_CLIENT_MAX +} vlanctl_bind_client_t; + + +/* + * vlanctl_bind defines three(!) hooks: + * NotifHook: When blog_notify is invoked, the bound hook is invoked. Based on + * event type the bound Blog client may perform a custom action. + * SC Hook: If this hook is defined, blog_activate() will pass a blog with + * necessary information for statical configuration. + * SD Hook: If this hook is defined, blog_deactivate() will pass a pointer + * to a network object with BlogActivateKey information. The + * respective flow entry will be deleted. + */ +typedef union { + struct { + uint8_t unused : 5; + uint8_t SN_HOOK : 1; + uint8_t SC_HOOK : 1; + uint8_t SD_HOOK : 1; + } bmap; + uint8_t hook_info; +} vlanctl_bind_t; + +typedef struct { + struct net_device *vlan_dev; + unsigned int vid; + int enable; +} vlanctl_vlan_t; + +typedef struct { + uint8_t mac[6]; + int enable; +} vlanctl_route_mac_t; + +typedef struct { + struct net_device *aggregate_vlan_dev; + struct net_device *deaggregate_vlan_dev; +} vlanctl_vlan_aggregate_t; + +typedef enum { + VLANCTL_BIND_NOTIFY_TPID, /* set interface tpid */ + VLANCTL_BIND_NOTIFY_VLAN, /* set vlan object */ + VLANCTL_BIND_NOTIFY_ROUTE_MAC, /* route mac create and delete */ + VLANCTL_BIND_NOTIFY_VLAN_AGGREGATE, /* set vlan aggregation */ + VLANCTL_BIND_DROP_PRECEDENCE_SET, /* rdpa_mw_drop_precedence_set */ +} vlanctl_bind_Notify_t; + +#if defined(CONFIG_BLOG) + +typedef uint32_t (* vlanctl_bind_ScHook_t)(Blog_t * blog_p, BlogTraffic_t traffic); + +typedef Blog_t * (* vlanctl_bind_SdHook_t)(uint32_t key, BlogTraffic_t traffic); + +typedef void (* vlanctl_bind_SnHook_t)(vlanctl_bind_Notify_t event, void *ptr); + +void vlanctl_bind_config(vlanctl_bind_ScHook_t vlanctl_bind_sc, + vlanctl_bind_SdHook_t vlanctl_bind_sd, + vlanctl_bind_SnHook_t vlanctl_bind_sn, + vlanctl_bind_client_t client, + vlanctl_bind_t bind); + + +int vlanctl_bind_activate(vlanctl_bind_client_t client); + +int vlanctl_notify(vlanctl_bind_Notify_t event, void *ptr, vlanctl_bind_client_t client); + +/* + *------------------------------------------------------------------------------ + * vlanctl_activate(): static configuration function of blog application + * pass a filled blog to the hook for configuration + *------------------------------------------------------------------------------ + */ +extern uint32_t vlanctl_activate( Blog_t * blog_p, vlanctl_bind_client_t client ); + +/* + *------------------------------------------------------------------------------ + * vlanctl_deactivate(): static deconfiguration function of blog application + *------------------------------------------------------------------------------ + */ +extern Blog_t * vlanctl_deactivate( uint32_t key, vlanctl_bind_client_t client ); + +#endif /* CONFIG_BLOG */ + +#endif /* ! _VLANCTL_BIND_ */ diff --git a/include/net/bcm_addrconf.h b/include/net/bcm_addrconf.h new file mode 100644 index 0000000000000000000000000000000000000000..a70385f1d4f88d22893409952b8030e74f6cc08f --- /dev/null +++ b/include/net/bcm_addrconf.h @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2003-2019 Broadcom +* All Rights Reserved +* +<:label-BRCM:2019:DUAL/GPL:standard + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ +#ifndef _BCM_ADDRCONF_H +#define _BCM_ADDRCONF_H + +void ipv6_del_addr(struct inet6_ifaddr *ifp); +int ipv6_generate_eui64(u8 *eui, struct net_device *dev); + +static inline int isULA(const struct in6_addr *addr) +{ + __be32 st; + + st = addr->s6_addr32[0]; + + /* RFC 4193 */ + if ((st & htonl(0xFE000000)) == htonl(0xFC000000)) + return 1; + else + return 0; +} + +static inline int isSpecialAddr(const struct in6_addr *addr) +{ + __be32 st; + + st = addr->s6_addr32[0]; + + /* RFC 5156 */ + if (((st & htonl(0xFFFFFFFF)) == htonl(0x20010db8)) || + ((st & htonl(0xFFFFFFF0)) == htonl(0x20010010))) + return 1; + else + return 0; +} + +int addrconf_update_lladdr(struct net_device *dev); + +#endif /* _BCM_ADDRCONF_H */ diff --git a/include/net/bcm_icmp.h b/include/net/bcm_icmp.h new file mode 100644 index 0000000000000000000000000000000000000000..a32760a92490d38b32b2c5eba9169fbca6920f78 --- /dev/null +++ b/include/net/bcm_icmp.h @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2003-2019 Broadcom +* All Rights Reserved +* +<:label-BRCM:2019:DUAL/GPL:standard + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ +#ifndef _BCM_ICMP_H +#define _BCM_ICMP_H + +struct icmp_bxm { + struct sk_buff *skb; + int offset; + int data_len; + + struct { + struct icmphdr icmph; + __be32 times[3]; + } data; + int head_len; + struct ip_options_data replyopts; +}; + +struct icmp_control { + bool (*handler)(struct sk_buff *skb); + short error; +}; + +extern const struct icmp_control icmp_pointers[]; + +void icmp_push_reply(struct icmp_bxm *icmp_param, + struct flowi4 *fl4, + struct ipcm_cookie *ipc, struct rtable **rt); +struct rtable *icmp_route_lookup(struct net *net, + struct flowi4 *fl4, + struct sk_buff *skb_in, + const struct iphdr *iph, + __be32 saddr, u8 tos, u32 mark, + int type, int code, + struct icmp_bxm *param); +void send_icmp_frag(struct sk_buff *skb_in, int type, int code, __be32 info); + +#endif /* _BCM_ICMP_H */ diff --git a/include/uapi/linux/bcm_atmdev.h b/include/uapi/linux/bcm_atmdev.h new file mode 100644 index 0000000000000000000000000000000000000000..a3febf166757817c343d44df38ae82b1d2234ba2 --- /dev/null +++ b/include/uapi/linux/bcm_atmdev.h @@ -0,0 +1,41 @@ +#ifndef __UAPI_BCM_ATMDEV_H__ +#define __UAPI_BCM_ATMDEV_H__ +/* +<:copyright-BRCM:2019:DUAL/GPL:standard + + Copyright (c) 2019 Broadcom + All Rights Reserved + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + +//#define ATM_EXTBACKENDIF _IOW('a',ATMIOC_SPECIAL+6,atm_backend_t) +//#define ATM_SETEXTFILT _IOW('a',ATMIOC_SPECIAL+7,atm_backend_t) + +#define ATM_BACKEND_RT2684 3 /* Routed RFC1483/2684 */ +#define ATM_BACKEND_BR2684_BCM 4 /* Bridged RFC1483/2684 uses Broadcom ATMAPI*/ +#define ATM_BACKEND_PPP_BCM 5 /* PPPoA uses Broadcom bcmxtmrt driver */ +#define ATM_BACKEND_PPP_BCM_DISCONN 6 /* PPPoA LCP disconnect */ +#define ATM_BACKEND_PPP_BCM_CLOSE_DEV 7 /* PPPoA close device */ + +#endif //__UAPI_BCM_ATMDEV_H__ diff --git a/include/uapi/linux/bcm_colors.h b/include/uapi/linux/bcm_colors.h new file mode 100644 index 0000000000000000000000000000000000000000..f8f913e505f905dc7c157dc1aab45fad12210456 --- /dev/null +++ b/include/uapi/linux/bcm_colors.h @@ -0,0 +1,93 @@ +/* + * <:copyright-BRCM:2016:DUAL/GPL:standard + * + * Copyright (c) 2016 Broadcom + * All Rights Reserved + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed + * to you under the terms of the GNU General Public License version 2 + * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, + * with the following added to such license: + * + * As a special exception, the copyright holders of this software give + * you permission to link this software with independent modules, and + * to copy and distribute the resulting executable under terms of your + * choice, provided that you also meet, for each linked independent + * module, the terms and conditions of the license of that module. + * An independent module is a module which is not derived from this + * software. The special exception does not apply to any modifications + * of the software. + * + * Not withstanding the above, under no circumstances may you combine + * this software in any way with any other Broadcom software provided + * under a license other than the GPL, without Broadcom's express prior + * written consent. + * + * :> + */ + +/*----------------------------------------------------------------------* + * NOTE: FOR USERSPACE USERS: + *----------------------------------------------------------------------* + *ALL USERSPACE DEVELOPERS MUST INCLUDE THIS FILE IN THEIR APPLICATIONS. + * + * EXAMPLE: + * #include <bcm_local_kernel_include/linux/bcm_colors.h> + *----------------------------------------------------------------------*/ + +/* + *-------------------------------------------------------------------------- + * Color encodings for console printing: + * + * This feature is controlled from top level make menuconfig, under + * Debug Selection>Enable Colorized Prints + * + * You may select a color specific to your subsystem by: + * #define CLRsys CLRg + * + * Usage: PRINT(CLRr "format" CLRNL); + *-------------------------------------------------------------------------- + */ + +#ifndef __UAPI_BCM_COLORS_H__ +#define __UAPI_BCM_COLORS_H__ + +#ifdef CONFIG_BCM_COLORIZE_PRINTS +#define BCMCOLOR(clr_code) clr_code +#else +#define BCMCOLOR(clr_code) +#endif + +/* White background */ +#define CLRr BCMCOLOR("\e[0;31m") /* red */ +#define CLRg BCMCOLOR("\e[0;32m") /* green */ +#define CLRy BCMCOLOR("\e[0;33m") /* yellow */ +#define CLRb BCMCOLOR("\e[0;34m") /* blue */ +#define CLRm BCMCOLOR("\e[0;35m") /* magenta */ +#define CLRc BCMCOLOR("\e[0;36m") /* cyan */ + +/* blacK "inverted" background */ +#define CLRrk BCMCOLOR("\e[0;31;40m") /* red on blacK */ +#define CLRgk BCMCOLOR("\e[0;32;40m") /* green on blacK */ +#define CLRyk BCMCOLOR("\e[0;33;40m") /* yellow on blacK */ +#define CLRmk BCMCOLOR("\e[0;35;40m") /* magenta on blacK */ +#define CLRck BCMCOLOR("\e[0;36;40m") /* cyan on blacK */ +#define CLRwk BCMCOLOR("\e[0;37;40m") /* whilte on blacK */ + +/* Colored background */ +#define CLRcb BCMCOLOR("\e[0;36;44m") /* cyan on blue */ +#define CLRyr BCMCOLOR("\e[0;33;41m") /* yellow on red */ +#define CLRym BCMCOLOR("\e[0;33;45m") /* yellow on magen */ + +/* Generic foreground colors */ +#define CLRhigh CLRm /* Highlight color */ +#define CLRbold CLRcb /* Bold color */ +#define CLRbold2 CLRym /* Bold2 color */ +#define CLRerr CLRyr /* Error color */ +#define CLRnorm BCMCOLOR("\e[0m") /* Normal color */ +#define CLRnl CLRnorm "\n" /* Normal + newline */ + +/* Each subsystem may define CLRsys */ + +#endif /* __BCM_COLORS_H__ */ diff --git a/include/uapi/linux/bcm_if_ether.h b/include/uapi/linux/bcm_if_ether.h new file mode 100644 index 0000000000000000000000000000000000000000..bbba398bee434be0df70dc4cb42d80939d8f951a --- /dev/null +++ b/include/uapi/linux/bcm_if_ether.h @@ -0,0 +1,37 @@ +/* +<:copyright-BRCM:2019:DUAL/GPL:standard + + Copyright (c) 2019 Broadcom + All Rights Reserved + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + +#ifndef _LINUX_BCM_IF_ETHER_H +#define _LINUX_BCM_IF_ETHER_H + +#define ETH_P_8021AG 0x8902 /* 802.1ag Connectivity Fault Mgmt */ +#define ETH_P_8023AH 0x8809 /* 802.3ah Ethernet OAM */ + + +#endif diff --git a/include/uapi/linux/bcm_maclimit.h b/include/uapi/linux/bcm_maclimit.h new file mode 100644 index 0000000000000000000000000000000000000000..dfe0a63e840f380f257889cba81c1d9c78d80a43 --- /dev/null +++ b/include/uapi/linux/bcm_maclimit.h @@ -0,0 +1,41 @@ +#ifndef __BCM_MACLIMIT_H_INCLUDED__ +#define __BCM_MACLIMIT_H_INCLUDED__ +/* +<:copyright-BRCM:2020:DUAL/GPL:standard + + Copyright (c) 2020 Broadcom + All Rights Reserved + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ +struct mac_limit +{ + unsigned int enable; //dev mac limit enabled + unsigned int max; //dev and lower-devs max allow + unsigned int max_zero_drop; //max zero value is drop or not + unsigned int drop_count; //exceed max drop count + unsigned int min; //dev mac learning min commit + unsigned int reserve; //reserved for lower-devs' min + unsigned int learning_count; //dev and lower-devs learning count +}; +#endif \ No newline at end of file diff --git a/include/uapi/linux/bcm_netlink.h b/include/uapi/linux/bcm_netlink.h new file mode 100644 index 0000000000000000000000000000000000000000..6edb055b020ceef57db1703958c2cfd503368668 --- /dev/null +++ b/include/uapi/linux/bcm_netlink.h @@ -0,0 +1,45 @@ +#ifndef __BCM_NETLINK_H_INCLUDED__ +#define __BCM_NETLINK_H_INCLUDED__ +/* +<:copyright-BRCM:2019:DUAL/GPL:standard + + Copyright (c) 2019 Broadcom + All Rights Reserved + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + +#define NETLINK_DPI 27 /* dpicore driver */ +#define NETLINK_DPI_QOS 28 /* DPI QoS */ +#define NETLINK_IGSC 29 /* for WIFI multicast igs sdb listing */ +#define NETLINK_BCM_MCAST 30 /* for multicast */ +#define NETLINK_WLCSM 31 /* for brcm wireless cfg[nvram]/statics/management extention */ + +/* Note that MAX netlink message ids is 32. Defined by MAX_LINKS + * macro in kernel/linux-<ver>/include/uapi/linux/netlink.h. + * Max netlink message ids have been reached and any new + * netlink message requirements must look at using NETLINK_GENERIC + * with a sub-type + */ + +#endif /* __BCM_NETLINK_H_INCLUDED__ */ diff --git a/include/uapi/linux/bcm_realtime.h b/include/uapi/linux/bcm_realtime.h new file mode 100644 index 0000000000000000000000000000000000000000..0d462bce7aa64699f3bc7f56ff97bb754094b0fc --- /dev/null +++ b/include/uapi/linux/bcm_realtime.h @@ -0,0 +1,77 @@ +/* +<:copyright-BRCM:2011:DUAL/GPL:standard + + Copyright (c) 2011 Broadcom + All Rights Reserved + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + +#ifndef _BCM_REALTIME_H_ +#define _BCM_REALTIME_H_ + +/* + * This file defines the real time priority levels used by the various + * threads in the system. It is important that all threads coordinate + * their priority levels so that the desired effect is achieved. + * These priorities are also related cgroups, so check the cgroups + * groupings and cpu allocations (if cgroups is enabled). + */ + +/** highest priority threads in the system. + * + * Threads at this priority require the absolute minium latency. However, + * they should only run very briefly (<2ms per run). + * These threads should also run at sched policy FIFO. + */ +#define BCM_RTPRIO_HIGH 75 + + +/** priority for the voip DSP. + * + * Note this is not for all voip threads, just the DSP thread. + * The other voice threads should be run at the other priorities that are + * defined. + */ +#define BCM_RTPRIO_VOIPDSP 35 + + +/** priority for all data forwarding. + * + * This is for data and video streaming. Not clear if we need to split out + * sub-categories here such as video, versus web data, versus voice. + * Probably need to use cgroups if a system needs to handle many types of + * streams. + * Threads running at this priority should use sched policy Round-Robin. + */ +#define BCM_RTPRIO_DATA 5 + +/** priority for all tasks that handle control messages related to data path. + * + * ex: bpm tasl handling allocation/free of data buffers. + * Threads running at this priority should use sched policy Round-Robin. + */ +#define BCM_RTPRIO_DATA_CONTROL 10 + +#endif /* _BCM_REALTIME_H_ */ + diff --git a/include/uapi/linux/netfilter/nf_conntrack_pt.h b/include/uapi/linux/netfilter/nf_conntrack_pt.h new file mode 100644 index 0000000000000000000000000000000000000000..108cf9825a5677b99bab1c9721b121466fe28d9a --- /dev/null +++ b/include/uapi/linux/netfilter/nf_conntrack_pt.h @@ -0,0 +1,9 @@ +#ifndef _NF_CONNTRACK_PT_H +#define _NF_CONNTRACK_PT_H +/* PT tracking. */ +#define PT_MAX_ENTRIES 100 +#define PT_MAX_PORTS 1000 +#define PT_MAX_EXPECTED 255 +#define PT_TIMEOUT 180 + +#endif /* _NF_CONNTRACK_PT_H */ diff --git a/include/uapi/linux/netfilter/xt_blog.h b/include/uapi/linux/netfilter/xt_blog.h new file mode 100755 index 0000000000000000000000000000000000000000..b7914fd3c64ff1145670c24c986c9b45d798d4e1 --- /dev/null +++ b/include/uapi/linux/netfilter/xt_blog.h @@ -0,0 +1,11 @@ +#ifndef _XT_BLOG_H +#define _XT_BLOG_H + +#include <linux/types.h> + +struct xt_blog { + __u8 tcp_pure_ack; + __u8 invert; +}; + +#endif /*_XT_BLOG_H*/ diff --git a/include/uapi/linux/netfilter/xt_flowlabel.h b/include/uapi/linux/netfilter/xt_flowlabel.h new file mode 100644 index 0000000000000000000000000000000000000000..f3df198dcd684fdbdc8a6851ec35c67c46eb1f67 --- /dev/null +++ b/include/uapi/linux/netfilter/xt_flowlabel.h @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2003-2019 Broadcom +* All Rights Reserved +* +<:label-BRCM:2019:DUAL/GPL:standard + +Unless you and Broadcom execute a separate written software license +agreement governing use of this software, this software is licensed +to you under the terms of the GNU General Public License version 2 +(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, +with the following added to such license: + + As a special exception, the copyright holders of this software give + you permission to link this software with independent modules, and + to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent + module, the terms and conditions of the license of that module. + An independent module is a module which is not derived from this + software. The special exception does not apply to any modifications + of the software. + +Not withstanding the above, under no circumstances may you combine +this software in any way with any other Broadcom software provided +under a license other than the GPL, without Broadcom's express prior +written consent. + +:> +*/ + + +/* IP tables module for matching the value of the IPv6 flowlabel field + * + * BRCM, Feb, 1. 2019. + */ + + +#ifndef _XT_FLOWLABEL_H +#define _XT_FLOWLABEL_H + +#include <linux/types.h> + +#define XT_FLOWLABEL_MAX cpu_to_be32(0x000FFFFF) + + +/* match info */ +struct xt_flowlabel_info { + __be32 flowlabel; + __u8 invert; +}; + + +#endif /* _XT_FLOWLABEL_H */ diff --git a/include/uapi/linux/netfilter/xt_mac_extend.h b/include/uapi/linux/netfilter/xt_mac_extend.h new file mode 100644 index 0000000000000000000000000000000000000000..1fbbc87b27c2f4cc07574a53a606e054dd8740bc --- /dev/null +++ b/include/uapi/linux/netfilter/xt_mac_extend.h @@ -0,0 +1,15 @@ +#ifndef _XT_MAC_EXTEND_H +#define _XT_MAC_EXTEND_H + +/* extend from xt_mac.h for MAC address extend match operations, + * i.e, MAC/mask. + * BRCM, Jan, 31. 2019. + */ + + +struct xt_mac_info_extend { + unsigned char srcaddr[ETH_ALEN]; + unsigned char msk[ETH_ALEN]; + int invert; +}; +#endif /*_XT_MAC_EXTEND_H*/ diff --git a/include/uapi/linux/netfilter_bridge/ebt_blog.h b/include/uapi/linux/netfilter_bridge/ebt_blog.h new file mode 100755 index 0000000000000000000000000000000000000000..181f17c3ce575a03d16dfb8abec7be8ec692c797 --- /dev/null +++ b/include/uapi/linux/netfilter_bridge/ebt_blog.h @@ -0,0 +1,12 @@ +#ifndef __LINUX_BRIDGE_EBT_BLOG_H +#define __LINUX_BRIDGE_EBT_BLOG_H + +#include <linux/types.h> + +struct ebt_blog_info +{ + __u8 tcp_pure_ack; + __u8 invert; +}; + +#endif diff --git a/include/uapi/linux/netfilter_bridge/ebt_ftos_t.h b/include/uapi/linux/netfilter_bridge/ebt_ftos_t.h new file mode 100644 index 0000000000000000000000000000000000000000..2e5099c7c2a58e43dd5c3b37db1e93b60b910f3d --- /dev/null +++ b/include/uapi/linux/netfilter_bridge/ebt_ftos_t.h @@ -0,0 +1,22 @@ +#ifndef __LINUX_BRIDGE_EBT_FTOS_T_H +#define __LINUX_BRIDGE_EBT_FTOS_T_H + +struct ebt_ftos_t_info +{ + int ftos_set; + unsigned char ftos; + // EBT_ACCEPT, EBT_DROP or EBT_CONTINUE or EBT_RETURN + int target; +}; +#define EBT_FTOS_TARGET "ftos" + +#define FTOS_TARGET 0x01 +#define FTOS_SETFTOS 0x02 +#define FTOS_WMMFTOS 0x04 +#define FTOS_8021QFTOS 0x08 + +#define DSCP_MASK_SHIFT 5 +#define PRIO_LOC_NFMARK 0 +#define PRIO_LOC_NFMASK 7 + +#endif diff --git a/include/uapi/linux/netfilter_bridge/ebt_ip6_extend.h b/include/uapi/linux/netfilter_bridge/ebt_ip6_extend.h new file mode 100644 index 0000000000000000000000000000000000000000..c18cd4cd1641613fcf950d1bc2e7320f73fa3ddc --- /dev/null +++ b/include/uapi/linux/netfilter_bridge/ebt_ip6_extend.h @@ -0,0 +1,32 @@ +/* + * ebt_ip6 + * + * Authors: + * Kuo-Lang Tseng <kuo-lang.tseng@intel.com> + * Manohar Castelino <manohar.r.castelino@intel.com> + * + * Jan 11, 2008 + * + * Extend by Broadcom at Jan 31, 2019 + */ +#ifndef __LINUX_BRIDGE_EBT_IP6_EXTEND_H +#define __LINUX_BRIDGE_EBT_IP6_EXTEND_H + +#include <linux/types.h> + +#define EBT_IP6_TCLASS_EXTEND 0x01 +#define EBT_IP6_FLOWLABEL_EXTEND 0x02 + +#define EBT_IP6_MASK_EXTEND (EBT_IP6_TCLASS_EXTEND | EBT_IP6_FLOWLABEL_EXTEND) +#define EBT_IP6_MATCH_EXTEND "ip6-extend" + +/* the same values are used for the invflags */ +struct ebt_ip6_extend_info { + __u8 flow_lbl[3]; + __u8 tclass[2]; + __u8 tclassmsk; + __u8 bitmask; + __u8 invflags; +}; + +#endif diff --git a/include/uapi/linux/netfilter_bridge/ebt_ip_extend.h b/include/uapi/linux/netfilter_bridge/ebt_ip_extend.h new file mode 100644 index 0000000000000000000000000000000000000000..a2bb057172bc53d84802ff2b60d6d52f3a0aa2bb --- /dev/null +++ b/include/uapi/linux/netfilter_bridge/ebt_ip_extend.h @@ -0,0 +1,37 @@ +/* + * ebt_ip + * + * Authors: + * Bart De Schuymer <bart.de.schuymer@pandora.be> + * + * April, 2002 + * + * Changes: + * added ip-sport and ip-dport + * Innominate Security Technologies AG <mhopf@innominate.com> + * September, 2002 + * + * Extend by Broadcom at Jan 31, 2019 + */ +#ifndef __LINUX_BRIDGE_EBT_IP_EXTEND_H +#define __LINUX_BRIDGE_EBT_IP_EXTEND_H + +#include <linux/types.h> + + +#define EBT_IP_TOS_EXTEND 0x01 +#define EBT_IP_DSCP_EXTEND 0x02 + +#define EBT_IP_MASK_EXTEND (EBT_IP_TOS_EXTEND | EBT_IP_DSCP_EXTEND) +#define EBT_IP_MATCH_EXTEND "ip-extend" + +/* the same values are used for the invflags */ +struct ebt_ip_extend_info { + __u8 tos[2]; + __u8 tosmask; + __u8 dscp; + __u8 bitmask; + __u8 invflags; +}; + +#endif diff --git a/include/uapi/linux/netfilter_bridge/ebt_qos_map.h b/include/uapi/linux/netfilter_bridge/ebt_qos_map.h new file mode 100644 index 0000000000000000000000000000000000000000..d45d7ff31d08cdf1c23478a45b908bbef2475e9a --- /dev/null +++ b/include/uapi/linux/netfilter_bridge/ebt_qos_map.h @@ -0,0 +1,9 @@ +#ifndef __LINUX_QOS_MAP_H +#define __LINUX_QOS_MAP_H + +struct ebt_qos_map_info +{ + int dscp2pbit; + int dscp2q; +}; +#endif diff --git a/include/uapi/linux/netfilter_bridge/ebt_reject.h b/include/uapi/linux/netfilter_bridge/ebt_reject.h new file mode 100644 index 0000000000000000000000000000000000000000..8b55769ef4836f5116c029f482dff1c344128646 --- /dev/null +++ b/include/uapi/linux/netfilter_bridge/ebt_reject.h @@ -0,0 +1,14 @@ +#if defined(CONFIG_BCM_KF_NETFILTER) +#ifndef __LINUX_BRIDGE_EBT_REJECT_H +#define __LINUX_BRIDGE_EBT_REJECT_H + +enum ebt_reject_with { + EBT_ICMP6_POLICY_FAIL +}; + +struct ebt_reject_info { + int with; /* reject type */ +}; + +#endif +#endif diff --git a/include/uapi/linux/netfilter_bridge/ebt_skbvlan_m.h b/include/uapi/linux/netfilter_bridge/ebt_skbvlan_m.h new file mode 100644 index 0000000000000000000000000000000000000000..13fdff40284a805d73c3d850b4c975cdd5e35c35 --- /dev/null +++ b/include/uapi/linux/netfilter_bridge/ebt_skbvlan_m.h @@ -0,0 +1,45 @@ +#ifndef __LINUX_BRIDGE_EBT_SKBVLAN_H +#define __LINUX_BRIDGE_EBT_SKBVLAN_H + +#include <linux/types.h> + +#define EBT_SKBVLAN_ID 0x0001 +#define EBT_SKBVLAN_PRIO 0x0002 +#define EBT_SKBVLAN_ENCAP 0x0004 +#define EBT_SKBVLAN_VLAN_TAG_0 0x0008 +#define EBT_SKBVLAN_VLAN_TAG_1 0x0010 +#define EBT_SKBVLAN_VLAN_TAG_2 0x0020 +#define EBT_SKBVLAN_VLAN_TAG_3 0x0040 +#define EBT_SKBVLAN_VLAN_TPID_0 0x0080 +#define EBT_SKBVLAN_VLAN_TPID_1 0x0100 +#define EBT_SKBVLAN_MASK (EBT_SKBVLAN_ID | EBT_SKBVLAN_PRIO | EBT_SKBVLAN_ENCAP | \ + EBT_SKBVLAN_VLAN_TAG_0 | EBT_SKBVLAN_VLAN_TAG_1 | EBT_SKBVLAN_VLAN_TAG_2 | \ + EBT_SKBVLAN_VLAN_TAG_3 |EBT_SKBVLAN_VLAN_TPID_0 | EBT_SKBVLAN_VLAN_TPID_1) + + + +#define EBT_SKBVLAN_MATCH "skbvlan" + +struct ebt_skbvlan_m_info { + __u16 id; /* VLAN ID {1-4095} */ + __u8 prio; /* VLAN User Priority {0-7} */ + __be16 encap; /* VLAN Encapsulated frame code {0-65535} */ + __u16 bitmask; /* Args bitmask bit 1=1 - ID arg, + bit 2=1 User-Priority arg, bit 3=1 encap*/ + __u16 invflags; /* Inverse bitmask bit 1=1 - inversed ID arg, + bit 2=1 - inversed Pirority arg */ + __be32 vlantag0[2]; + __be32 vlanmask0; + __be32 vlantag1[2]; + __be32 vlanmask1; + __be32 vlantag2[2]; + __be32 vlanmask2; + __be32 vlantag3[2]; + __be32 vlanmask3; + __be16 vlantpid0; + __be16 vlantpid1; +}; + + +#endif /* __LINUX_BRIDGE_EBT_SKBVLAN_H */ + diff --git a/include/uapi/linux/netfilter_bridge/ebt_time.h b/include/uapi/linux/netfilter_bridge/ebt_time.h new file mode 100644 index 0000000000000000000000000000000000000000..f47b531d7b9b8322d2fa71527c37950a054ec23c --- /dev/null +++ b/include/uapi/linux/netfilter_bridge/ebt_time.h @@ -0,0 +1,14 @@ +#ifndef __LINUX_BRIDGE_EBT_TIME_H +#define __LINUX_BRIDGE_EBT_TIME_H + + +struct ebt_time_info { + u_int8_t days_match; /* 1 bit per day. -SMTWTFS */ + u_int16_t time_start; /* 0 < time_start < 23*60+59 = 1439 */ + u_int16_t time_stop; /* 0:0 < time_stat < 23:59 */ + u_int8_t kerneltime; /* ignore skb time (and use kerneltime) or not. */ +}; + +#define EBT_TIME_MATCH "time" + +#endif /* __LINUX_BRIDGE_EBT_TIME_H */ diff --git a/include/uapi/linux/netfilter_bridge/ebt_u32.h b/include/uapi/linux/netfilter_bridge/ebt_u32.h new file mode 100644 index 0000000000000000000000000000000000000000..2cd1c043b80455d440e390e280d33ca3f70266fa --- /dev/null +++ b/include/uapi/linux/netfilter_bridge/ebt_u32.h @@ -0,0 +1,55 @@ +/* + * ebt_u32 + * + * Authors: + * extend by Broadcom at Jan 24, 2019 + * + * + */ + +#ifndef __LINUX_BRIDGE_EBT_U32_H +#define __LINUX_BRIDGE_EBT_U32_H + +#include <linux/types.h> + +enum ebt_u32_ops { + EBT_U32_AND, + EBT_U32_LEFTSH, + EBT_U32_RIGHTSH, + EBT_U32_AT, +}; + +struct ebt_u32_location_element { + __u32 number; + __u8 nextop; +}; + +struct ebt_u32_value_element { + __u32 min; + __u32 max; +}; + +/* + * Any way to allow for an arbitrary number of elements? + * For now, I settle with a limit of 10 each. + */ +#define EBT_U32_MAXSIZE 10 + +#define EBT_U32_MATCH "u32" + + +struct ebt_u32_test { + struct ebt_u32_location_element location[EBT_U32_MAXSIZE+1]; + struct ebt_u32_value_element value[EBT_U32_MAXSIZE+1]; + __u8 nnums; + __u8 nvalues; +}; + +struct ebt_u32_info { + struct ebt_u32_test tests[EBT_U32_MAXSIZE+1]; + __u8 ntests; + __u8 invert; +}; + +#endif + diff --git a/include/uapi/linux/netfilter_bridge/ebt_vtag_t.h b/include/uapi/linux/netfilter_bridge/ebt_vtag_t.h new file mode 100644 index 0000000000000000000000000000000000000000..cd803cc10aaeaa3277bd0579d4f6c8dee61fd610 --- /dev/null +++ b/include/uapi/linux/netfilter_bridge/ebt_vtag_t.h @@ -0,0 +1,13 @@ +#ifndef __EBT_VTAG_T_H__ +#define __EBT_VTAG_T_H__ + + +struct ebt_vtag_t_info +{ + int vtag; + /* EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN */ + int target; +}; + +#endif //__EBT_VTAG_T_H__ + diff --git a/include/uapi/linux/netfilter_bridge/ebt_wmm_mark_t.h b/include/uapi/linux/netfilter_bridge/ebt_wmm_mark_t.h new file mode 100644 index 0000000000000000000000000000000000000000..629f39c58a65950b51b61d849e9555d86fff9a2f --- /dev/null +++ b/include/uapi/linux/netfilter_bridge/ebt_wmm_mark_t.h @@ -0,0 +1,27 @@ +#ifndef __LINUX_BRIDGE_EBT_MARK_T_H +#define __LINUX_BRIDGE_EBT_MARK_T_H + +#define WMM_MARK_DSCP 1 +#define WMM_MARK_8021D 2 + +#define WMM_MARK_DSCP_STR "dscp" +#define WMM_MARK_8021D_STR "vlan" + +#define PRIO_LOC_NFMARK 0 +#define PRIO_LOC_NFMASK 7 + +#define WMM_DSCP_MASK_SHIFT 5 +#define WMM_MARK_VALUE_NONE -1 + + +struct ebt_wmm_mark_t_info +{ + int mark; + int markpos; + int markset; + /* EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN */ + int target; +}; +#define EBT_WMM_MARK_TARGET "wmm-mark" + +#endif