static ssize_t hwf_nfp_debug_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned int off = 0; MV_STATUS status; MV_U32 hit; MV_NFP_CT_KEY key; if (!strcmp(attr->attr.name, "first_get")) { status = nfp_ct_first_get(&key, &hit); } else if (!strcmp(attr->attr.name, "mostly_get")) { status = nfp_ct_mostly_used_get(&key, &hit); } else { status = nfp_ct_next_get(&key, &hit); } if (status != MV_OK) { off += mvOsSPrintf(buf+off,"No rules found.\n"); return off; } if (key.family == AF_INET) { off += mvOsSPrintf(buf+off, "\nfamily: IPv4\n"); off += mvOsSPrintf(buf+off, "sip: "MV_IPQUAD_FMT"\n", MV_IPQUAD(key.src_l3)); off += mvOsSPrintf(buf+off, "dip: "MV_IPQUAD_FMT"\n", MV_IPQUAD(key.dst_l3)); } else { off += mvOsSPrintf(buf+off, "\nfamily: IPv6\n"); off += mvOsSPrintf(buf+off, "sip: "MV_IP6_FMT"\n", MV_IP6_ARG(key.src_l3)); off += mvOsSPrintf(buf+off, "dip: "MV_IP6_FMT"\n", MV_IP6_ARG(key.dst_l3)); } off += mvOsSPrintf(buf+off, "sport: %hu\n", key.sport); off += mvOsSPrintf(buf+off, "dport: %hu\n", key.dport); off += mvOsSPrintf(buf+off, "proto: %hhu\n\n", key.proto); off += mvOsSPrintf(buf+off, "hit counter: %d\n\n", hit); return off; }
int do_ct_age_del_forward(const char *name, int family, unsigned char *sip, unsigned char *dip, int sport, int dport, char *protoStr, int mode) { int proto; proto = get_protocol_num(protoStr); if (!proto) return 1; NFP_SYSFS_DBG(printk(KERN_INFO "nfp_ct_%s( IPv%d , ", name, family)); if (family == AF_INET) NFP_SYSFS_DBG(printk(MV_IPQUAD_FMT" , "MV_IPQUAD_FMT, MV_IPQUAD(sip), MV_IPQUAD(dip))); else NFP_SYSFS_DBG(printk(MV_IP6_FMT" , "MV_IP6_FMT, MV_IP6_ARG(sip), MV_IP6_ARG(dip))); if (!strcmp(name, "forward")) { NFP_SYSFS_DBG(printk(KERN_INFO " , %hu , %hu, %d , %d )\n", sport, dport, proto, mode)); nfp_ct_filter_set(family, sip, dip, sport, dport, proto, mode); } else { NFP_SYSFS_DBG(printk(KERN_INFO " , %hu , %hu, %d )\n", sport, dport, proto)); if (!strcmp(name, "del")) nfp_ct_del(family, sip, dip, sport, dport, proto); else printk(KERN_INFO "age: %d\n", nfp_ct_age(family, sip, dip, sport, dport, proto)); } return 0; }
void print_fib_del_age(int f, unsigned char *sip, unsigned char *dip, char *name) { if (f == AF_INET) { printk(KERN_INFO "%s_fib_rule(IPV4 , "MV_IPQUAD_FMT" , "MV_IPQUAD_FMT" )\n", name, MV_IPQUAD(sip), MV_IPQUAD(dip)); } else { printk(KERN_INFO "%s_fib_rule(IPV6 , "MV_IP6_FMT" , ", name, MV_IP6_ARG(sip)); printk(KERN_INFO MV_IP6_FMT")\n", MV_IP6_ARG(dip)); } }
/* ip printers */ void print_fib_add(int f, unsigned char *sip, unsigned char *dip, int oif, unsigned char *gtw) { if (f == AF_INET) { printk(KERN_INFO "add_fib_rule(IPV4 , "MV_IPQUAD_FMT" , "MV_IPQUAD_FMT" , %d, "MV_IPQUAD_FMT" )\n", MV_IPQUAD(sip), MV_IPQUAD(dip), oif, MV_IPQUAD(gtw)); } else { printk(KERN_INFO "add_fib_rule(IPV6 , "MV_IP6_FMT" , ", MV_IP6_ARG(sip)); printk(KERN_INFO MV_IP6_FMT" , %d , ", MV_IP6_ARG(dip), oif); printk(KERN_INFO MV_IP6_FMT" )\n", MV_IP6_ARG(gtw)); } }
void print_arp_del_age(int f, unsigned char *gtw, char *name) { if (f == AF_INET) printk(KERN_INFO "nfp_arp_%s(IPV4, "MV_IPQUAD_FMT" )\n", name, MV_IPQUAD(gtw)); else printk(KERN_INFO "nfp_arp_%s(IPV6, "MV_IP6_FMT" )\n", name, MV_IP6_ARG(gtw)); }
static ssize_t do_print_local_key(struct device *dev, struct device_attribute *attr, char *buf) { unsigned int off = 0; if (!key.init) { off += mvOsSPrintf(buf+off, "Print_local_key: local key is not initialized.\n"); goto key_print_out; } off += mvOsSPrintf(buf+off, "Local key:\n"); off += mvOsSPrintf(buf+off, " family: IPv4\n"); off += mvOsSPrintf(buf+off, " sip: "MV_IPQUAD_FMT"\n", MV_IPQUAD(key.sip)); off += mvOsSPrintf(buf+off, " dip: "MV_IPQUAD_FMT"\n", MV_IPQUAD(key.dip)); off += mvOsSPrintf(buf+off, " sport: %hu\n", key.sport); off += mvOsSPrintf(buf+off, " dport: %hu\n", key.dport); off += mvOsSPrintf(buf+off, " proto: %hhu\n\n", key.proto); key_print_out: return off; }
void print_arp_add(int f, unsigned char *gtw, MV_U8 *mac) { if (f == AF_INET) { printk(KERN_INFO "nfp_arp_add(IPV4, "MV_IPQUAD_FMT" , "MV_MACQUAD_FMT" )\n", MV_IPQUAD(gtw), MV_MACQUAD(mac)); } else { printk(KERN_INFO "nfp_arp_add(IPV6, "MV_IP6_FMT" , "MV_MACQUAD_FMT" )\n", MV_IP6_ARG(gtw), MV_MACQUAD(mac)); } }
MV_STATUS l2fw_add(MV_U32 srcIP, MV_U32 dstIP, int port) { L2FW_RULE *l2fw_rule; MV_U8 *srcIPchr, *dstIPchr; MV_U32 hash = mv_jhash_3words(srcIP, dstIP, (MV_U32) 0, l2fw_jhash_iv); hash &= L2FW_HASH_MASK; if (numHashEntries == L2FW_HASH_SIZE) { printk(KERN_INFO "cannot add entry, hash table is full, there are %d entires \n", L2FW_HASH_SIZE); return MV_ERROR; } srcIPchr = (MV_U8 *)&(srcIP); dstIPchr = (MV_U8 *)&(dstIP); #ifdef CONFIG_MV_ETH_L2FW_DEBUG mvOsPrintf("srcIP=%x dstIP=%x in %s\n", srcIP, dstIP, __func__); mvOsPrintf("srcIp = %u.%u.%u.%u in %s\n", MV_IPQUAD(srcIPchr), __func__); mvOsPrintf("dstIp = %u.%u.%u.%u in %s\n", MV_IPQUAD(dstIPchr), __func__); #endif l2fw_rule = l2fw_lookup(srcIP, dstIP); if (l2fw_rule) return MV_OK; l2fw_rule = (L2FW_RULE *)mvOsMalloc(sizeof(L2FW_RULE)); if (!l2fw_rule) { mvOsPrintf("%s: OOM\n", __func__); return MV_FAIL; } #ifdef CONFIG_MV_ETH_L2FW_DEBUG mvOsPrintf("adding a rule to l2fw hash in %s\n", __func__); #endif l2fw_rule->srcIP = srcIP; l2fw_rule->dstIP = dstIP; l2fw_rule->port = port; l2fw_rule->next = l2fw_hash[hash]; l2fw_hash[hash] = l2fw_rule; numHashEntries++; return MV_OK; }
static void mvNfpFibRulePrint(NFP_RULE_FIB *fib) { if (fib->family == MV_INET) { mvOsPrintf("IPv4: " MV_IPQUAD_FMT "->" MV_IPQUAD_FMT"\n", MV_IPQUAD(*((u32 *) fib->srcL3)), MV_IPQUAD(*((u32 *) fib->dstL3))); } else { mvOsPrintf("IPv6: " MV_IP6_FMT "->" MV_IP6_FMT"\n", MV_IP6_ARG(fib->srcL3), MV_IP6_ARG(fib->dstL3)); } mvOsPrintf(" mh=%2.2x:%2.2x da=" MV_MACQUAD_FMT " sa=" MV_MACQUAD_FMT "\n", ((MV_U8 *) &fib->mh)[0], ((MV_U8 *) &fib->mh)[1], MV_MACQUAD(fib->da), MV_MACQUAD(fib->sa)); mvOsPrintf(" outport=%d, outdev=%p, flags=0x%x, ref=%d, age=%x, fib=%p, pnc=%p\n", fib->outport, fib->outdev, fib->flags, fib->ref, fib->age, fib, fib->pnc); mvOsPrintf(" Flags: "); if (fib->flags & NFP_F_DYNAMIC) mvOsPrintf("NFP_F_DYNAMIC "); if (fib->flags & NFP_F_STATIC) mvOsPrintf("NFP_F_STATIC "); if (fib->flags & NFP_F_INV) mvOsPrintf("NFP_F_INV "); if (fib->flags & NFP_F_SNAT) mvOsPrintf("NFP_F_SNAT "); if (fib->flags & NFP_F_DNAT) mvOsPrintf("NFP_F_DNAT "); if (fib->flags & NFP_F_BUSY) mvOsPrintf("NFP_F_BUSY "); if (fib->flags & NFP_F_PPPOE_ADD) mvOsPrintf("NFP_F_PPPOE_ADD "); if (fib->flags & NFP_F_PPPOE_REMOVE) mvOsPrintf("NFP_F_PPPOE_REMOVE "); if (fib->flags & NFP_F_HWF) mvOsPrintf("NFP_F_HWF "); if (fib->flags & NFP_F_BRIDGE) mvOsPrintf("NFP_F_BRIDGE "); mvOsPrintf("\n"); }
void l2fw_dump(void) { MV_U32 i = 0; L2FW_RULE *currRule; MV_U8 *srcIP, *dstIP; mvOsPrintf("\nPrinting L2fw Rule Database: \n"); mvOsPrintf("*******************************\n"); for (i = 0; i < L2FW_HASH_SIZE; i++) { currRule = l2fw_hash[i]; srcIP = (MV_U8 *)&(currRule->srcIP); dstIP = (MV_U8 *)&(currRule->dstIP); while (currRule != NULL) { mvOsPrintf("%u.%u.%u.%u->%u.%u.%u.%u out port=%d (hash=%x)\n", MV_IPQUAD(srcIP), MV_IPQUAD(dstIP), currRule->port, i); currRule = currRule->next; } } }
int do_ct_tbf(const char *name, int family, unsigned char *sip, unsigned char *dip, int sport, int dport, char *protoStr, int tbfIndex) { int proto; proto = get_protocol_num(protoStr); if (!proto) return 1; NFP_SYSFS_DBG(printk(KERN_INFO "nfp_ct_%s( IPv%d , ", name, family)); if (family == AF_INET) NFP_SYSFS_DBG(printk(KERN_INFO MV_IPQUAD_FMT" , "MV_IPQUAD_FMT, MV_IPQUAD(sip), MV_IPQUAD(dip))); else NFP_SYSFS_DBG(printk(KERN_INFO MV_IP6_FMT" , "MV_IP6_FMT, MV_IP6_ARG(sip), MV_IP6_ARG(dip))); if (!strcmp(name, "rate_limit_set")) { NFP_SYSFS_DBG(printk(KERN_INFO " , %hu , %hu, %d , %d )\n", sport, dport, proto, tbfIndex)); nfp_ct_rate_limit_set(family, sip, dip, sport, dport, proto, tbfIndex); } else { NFP_SYSFS_DBG(printk(KERN_INFO " , %hu , %hu, %d )\n", sport, dport, proto)); nfp_ct_rate_limit_del(family, sip, dip, sport, dport, proto); } return 0; }
mvOsMemset(nat_hash, 0, bytes); mvOsPrintf("NFP (nat) init %d entries, %d bytes\n", NFP_NAT_HASH_SIZE, bytes); return MV_OK; } static MV_VOID mvNfpNatRulePrint(NFP_RULE_NAT *nat) { mvOsPrintf(MV_IPQUAD_FMT":%d" "->"MV_IPQUAD_FMT":%d" " %-2d " "%s:"MV_IPQUAD_FMT" " "age=%x (%p)\n", MV_IPQUAD(nat->sip), MV_16BIT_BE(nat->ports & 0xFFFF), MV_IPQUAD(nat->dip), MV_16BIT_BE(nat->ports >> 16), nat->proto, nat->flags & NFP_F_DNAT ? "DNAT" : "SNAT", MV_IPQUAD(nat->nip), nat->age, nat); } static INLINE MV_U32 mvNfpNatHash(NFP_RULE_NAT *nat) { int family = MV_INET; return mv_jhash_2addr(family, (const MV_U8 *)&nat->sip, (const MV_U8 *)&nat->dip, nat->ports | nat->proto, mgr_rule_jhash_iv); } static INLINE NFP_RULE_NAT *mvNfpNatLookup(NFP_RULE_NAT *nat2) {
static inline int mv_eth_l2fw_rx(struct eth_port *pp, int rx_todo, int rxq) { struct eth_port *new_pp; L2FW_RULE *l2fw_rule; MV_NETA_RXQ_CTRL *rx_ctrl = pp->rxq_ctrl[rxq].q; int rx_done, rx_filled; struct neta_rx_desc *rx_desc; u32 rx_status = MV_OK; struct eth_pbuf *pkt; struct eth_pbuf *newpkt = NULL; struct bm_pool *pool; MV_STATUS status = MV_OK; struct eth_port_l2fw *ppl2fw = mv_eth_ports_l2fw[pp->port]; MV_IP_HEADER *pIph = NULL; MV_U8 *pData; int ipOffset; rx_done = mvNetaRxqBusyDescNumGet(pp->port, rxq); mvOsCacheIoSync(); if (rx_todo > rx_done) rx_todo = rx_done; rx_done = 0; rx_filled = 0; /* Fairness NAPI loop */ while (rx_done < rx_todo) { #ifdef CONFIG_MV_ETH_RX_DESC_PREFETCH rx_desc = mv_eth_rx_prefetch(pp, rx_ctrl, rx_done, rx_todo); if (!rx_desc) printk(KERN_INFO "rx_desc is NULL in %s\n", __func__); #else rx_desc = mvNetaRxqNextDescGet(rx_ctrl); mvOsCacheLineInv(NULL, rx_desc); prefetch(rx_desc); #endif /* CONFIG_MV_ETH_RX_DESC_PREFETCH */ rx_done++; rx_filled++; pkt = (struct eth_pbuf *)rx_desc->bufCookie; if (!pkt) { printk(KERN_INFO "pkt is NULL in ; rx_done=%d %s\n", rx_done, __func__); return rx_done; } pool = &mv_eth_pool[pkt->pool]; rx_status = rx_desc->status; if (((rx_status & NETA_RX_FL_DESC_MASK) != NETA_RX_FL_DESC_MASK) || (rx_status & NETA_RX_ES_MASK)) { STAT_ERR(pp->stats.rx_error++); if (pp->dev) pp->dev->stats.rx_errors++; mv_eth_rxq_refill(pp, rxq, pkt, pool, rx_desc); continue; } pkt->bytes = rx_desc->dataSize - (MV_ETH_CRC_SIZE + MV_ETH_MH_SIZE); pData = pkt->pBuf + pkt->offset; #ifdef CONFIG_MV_ETH_PNC ipOffset = NETA_RX_GET_IPHDR_OFFSET(rx_desc); #else if ((rx_desc->status & ETH_RX_VLAN_TAGGED_FRAME_MASK)) ipOffset = MV_ETH_MH_SIZE + sizeof(MV_802_3_HEADER) + MV_VLAN_HLEN; else ipOffset = MV_ETH_MH_SIZE + sizeof(MV_802_3_HEADER); #endif pIph = (MV_IP_HEADER *)(pData + ipOffset); if (pIph == NULL) { printk(KERN_INFO "pIph==NULL in %s\n", __func__); continue; } #ifdef CONFIG_MV_ETH_L2FW_DEBUG if (pIph) { MV_U8 *srcIP, *dstIP; srcIP = (MV_U8 *)&(pIph->srcIP); dstIP = (MV_U8 *)&(pIph->dstIP); printk(KERN_INFO "%u.%u.%u.%u->%u.%u.%u.%u in %s\n", MV_IPQUAD(srcIP), MV_IPQUAD(dstIP), __func__); } else printk(KERN_INFO "pIph is NULL in %s\n", __func__); #endif if (espEnabled) new_pp = mv_eth_ports[ppl2fw->txPort]; else { l2fw_rule = l2fw_lookup(pIph->srcIP, pIph->dstIP); if (!l2fw_rule) { #ifdef CONFIG_MV_ETH_L2FW_DEBUG printk(KERN_INFO "l2fw_lookup() failed in %s\n", __func__); #endif mv_eth_rxq_refill(pp, rxq, pkt, pool, rx_desc); continue; } #ifdef CONFIG_MV_ETH_L2FW_DEBUG printk(KERN_INFO "l2fw_lookup() is ok l2fw_rule->port=%d in %s\n", l2fw_rule->port, __func__); #endif new_pp = mv_eth_ports[l2fw_rule->port]; } switch (ppl2fw->cmd) { case TX_AS_IS: #ifdef CONFIG_MV_ETH_L2SEC if (espEnabled) { status = handleEsp(pkt, rx_desc, new_pp, pp->port); } else #endif status = mv_eth_l2fw_tx(pkt, new_pp, 0, rx_desc); break; case SWAP_MAC: mvOsCacheLineInv(NULL, pkt->pBuf + pkt->offset); l2fw_swap_mac(pkt); mvOsCacheLineFlush(NULL, pkt->pBuf+pkt->offset); status = mv_eth_l2fw_tx(pkt, new_pp, 0, rx_desc); break; case COPY_AND_SWAP: if (pkt->bytes >= l2fw_xor_threshold) { newpkt = eth_l2fw_copy_packet_withXor(pkt); if (newpkt) status = mv_eth_l2fw_tx(newpkt, new_pp, 1, rx_desc); else status = MV_ERROR; } else { newpkt = eth_l2fw_copy_packet_withoutXor(pkt); if (newpkt) status = mv_eth_l2fw_tx(newpkt, new_pp, 0, rx_desc); else status = MV_ERROR; } } if (status == MV_OK) { mvOsCacheLineInv(NULL, rx_desc); /* we do not need the pkt , we do not do anything with it*/ if ((ppl2fw->cmd == COPY_AND_SWAP) && !(espEnabled)) mv_eth_pool_put(pool, pkt); continue; } else if (status == MV_DROPPED) { mv_eth_rxq_refill(pp, rxq, pkt, pool, rx_desc); if ((ppl2fw->cmd == COPY_AND_SWAP) && !(espEnabled)) mv_eth_pool_put(pool, newpkt); continue; } else if (status == MV_ERROR) { printk(KERN_INFO "MV_ERROR in %s\n", __func__); mv_eth_rxq_refill(pp, rxq, pkt, pool, rx_desc); } } /* of while */ /* Update RxQ management counters */ mvOsCacheIoSync(); mvNetaRxqDescNumUpdate(pp->port, rxq, rx_done, rx_filled); return rx_done; }
MV_STATUS l2fw_add_ip(const char *buf) { char *addr1, *addr2; L2FW_RULE *l2fw_rule; MV_U32 srcIP; MV_U32 dstIP; MV_U8 *srcIPchr, *dstIPchr; char dest1[15]; char dest2[15]; char *portStr; int offset1, offset2, port; MV_U32 hash = 0; if (numHashEntries == L2FW_HASH_SIZE) { printk(KERN_INFO "cannot add entry, hash table is full, there are %d entires \n", L2FW_HASH_SIZE); return MV_ERROR; } memset(dest1, 0, sizeof(dest1)); memset(dest2, 0, sizeof(dest2)); addr1 = strchr(buf, ','); addr2 = strchr(addr1+1, ','); offset1 = addr1-buf; offset2 = addr2-addr1; if (!addr1) { printk(KERN_INFO "first separating comma (',') missing in input in %s\n", __func__); return MV_FAIL; } if (!addr2) { printk(KERN_INFO "second separating comma (',') missing in input in %s\n", __func__); return MV_FAIL; } strncpy(dest1, buf, addr1-buf); srcIP = in_aton(dest1); strncpy(dest2, buf+offset1+1, addr2-addr1-1); dstIP = in_aton(dest2); srcIPchr = (MV_U8 *)&(srcIP); dstIPchr = (MV_U8 *)&(dstIP); portStr = addr2+1; if (*portStr == 'D') { L2FW_RULE *l2fw_rule_to_del, *prev; hash = mv_jhash_3words(srcIP, dstIP, (MV_U32) 0, l2fw_jhash_iv); hash &= L2FW_HASH_MASK; l2fw_rule_to_del = l2fw_hash[hash]; prev = NULL; while (l2fw_rule_to_del) { if ((l2fw_rule_to_del->srcIP == srcIP) && (l2fw_rule_to_del->dstIP == dstIP)) { if (prev) prev->next = l2fw_rule_to_del->next; else l2fw_hash[hash] = l2fw_rule_to_del->next; mvOsPrintf("%u.%u.%u.%u->%u.%u.%u.%u deleted\n", MV_IPQUAD(srcIPchr), MV_IPQUAD(dstIPchr)); mvOsFree(l2fw_rule_to_del); numHashEntries--; return MV_OK; } prev = l2fw_rule_to_del; l2fw_rule_to_del = l2fw_rule_to_del->next; } mvOsPrintf("%u.%u.%u.%u->%u.%u.%u.%u : entry not found\n", MV_IPQUAD(srcIPchr), MV_IPQUAD(dstIPchr)); return MV_NOT_FOUND; } port = atoi(portStr); hash = mv_jhash_3words(srcIP, dstIP, (MV_U32) 0, l2fw_jhash_iv); hash &= L2FW_HASH_MASK; l2fw_rule = l2fw_lookup(srcIP, dstIP); if (l2fw_rule) { mvOsPrintf("%u.%u.%u.%u->%u.%u.%u.%u : entry already exist\n", MV_IPQUAD(srcIPchr), MV_IPQUAD(dstIPchr)); return MV_OK; } l2fw_rule = (L2FW_RULE *)mvOsMalloc(sizeof(L2FW_RULE)); if (!l2fw_rule) { mvOsPrintf("%s: OOM\n", __func__); return MV_FAIL; } #ifdef CONFIG_MV_ETH_L2FW_DEBUG mvOsPrintf("adding a rule to l2fw hash in %s\n", __func__); #endif l2fw_rule->srcIP = srcIP; l2fw_rule->dstIP = dstIP; l2fw_rule->port = port; l2fw_rule->next = l2fw_hash[hash]; l2fw_hash[hash] = l2fw_rule; numHashEntries++; return MV_OK; }