diff options
author | Hanhui <hanhui@acoinfo.com> | 2020-09-29 10:02:27 (GMT) |
---|---|---|
committer | Hanhui <hanhui@acoinfo.com> | 2020-09-29 10:02:27 (GMT) |
commit | 6bdb7542d4add740326d0ca005124def7c4d014c (patch) | |
tree | f013e855a22e7c8d39af97f7e24ba53ad2b2b5ac /SylixOS | |
parent | 8be77112f396363a45f1250dbb16881cb627da98 (diff) | |
download | libsylixos-6bdb7542d4add740326d0ca005124def7c4d014c.zip libsylixos-6bdb7542d4add740326d0ca005124def7c4d014c.tar.gz libsylixos-6bdb7542d4add740326d0ca005124def7c4d014c.tar.bz2 |
Add IP MAC strictly binding support.
Diffstat (limited to 'SylixOS')
-rw-r--r-- | SylixOS/include/net/if_arp.h | 1 | ||||
-rw-r--r-- | SylixOS/include/network/lwip/etharp.h | 2 | ||||
-rw-r--r-- | SylixOS/include/network/lwip/netifapi.h | 3 | ||||
-rw-r--r-- | SylixOS/net/lwip/lwip_arpctl.c | 28 | ||||
-rw-r--r-- | SylixOS/net/lwip/proc/lwip_proc.c | 7 | ||||
-rw-r--r-- | SylixOS/net/lwip/src/api/netifapi.c | 2 | ||||
-rw-r--r-- | SylixOS/net/lwip/src/core/ipv4/etharp.c | 139 |
7 files changed, 167 insertions, 15 deletions
diff --git a/SylixOS/include/net/if_arp.h b/SylixOS/include/net/if_arp.h index 90c9e0d..c39c68c 100644 --- a/SylixOS/include/net/if_arp.h +++ b/SylixOS/include/net/if_arp.h @@ -104,6 +104,7 @@ struct arpreq { #define ATF_PERM 0x04 /* permanent entry */ #define ATF_PUBL 0x08 /* publish entry (respond for other host) */ #define ATF_USETRAILERS 0x10 /* has requested trailers */ +#define ATF_STRICT 0x8000 /* Bind IP and MAC strictly */ /********************************************************************************************************* * arp ioctl command diff --git a/SylixOS/include/network/lwip/etharp.h b/SylixOS/include/network/lwip/etharp.h index 35ad151..3a99f8d 100644 --- a/SylixOS/include/network/lwip/etharp.h +++ b/SylixOS/include/network/lwip/etharp.h @@ -95,7 +95,7 @@ err_t etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, str #if ETHARP_SUPPORT_STATIC_ENTRIES err_t etharp_add_static_entry(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr); -err_t etharp_remove_static_entry(const ip4_addr_t *ipaddr); +err_t etharp_remove_static_entry(const ip4_addr_t *ipaddr, u8_t force /* SylixOS Add force delete */); #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ #ifdef SYLIXOS /* SylixOS Add Traversal ARP table */ diff --git a/SylixOS/include/network/lwip/netifapi.h b/SylixOS/include/network/lwip/netifapi.h index 3bf0295..5fbafdb 100644 --- a/SylixOS/include/network/lwip/netifapi.h +++ b/SylixOS/include/network/lwip/netifapi.h @@ -54,6 +54,9 @@ extern "C" { /* Used for netfiapi_arp_* APIs */ enum netifapi_arp_entry { NETIFAPI_ARP_PERM /* Permanent entry */ +#ifdef SYLIXOS + , NETIFAPI_ARP_COM +#endif /* SYLIXOS */ /* Other entry types can be added here */ }; diff --git a/SylixOS/net/lwip/lwip_arpctl.c b/SylixOS/net/lwip/lwip_arpctl.c index 8776fc7..def95ea 100644 --- a/SylixOS/net/lwip/lwip_arpctl.c +++ b/SylixOS/net/lwip/lwip_arpctl.c @@ -17,6 +17,8 @@ ** 文件创建日期: 2017 年 12 月 08 日 ** ** 描 述: ioctl ARP 支持. +** +2020.09.28 加入 IP MAC 强绑定支持. *********************************************************************************************************/ #define __SYLIXOS_KERNEL #include "SylixOS.h" @@ -38,6 +40,7 @@ #define ETHARP_FLAG_TRY_HARD 1 #define ETHARP_FLAG_FIND_ONLY 2 #define ETHARP_FLAG_STATIC_ENTRY 4 +#define ETHARP_FLAG_STRICT_ENTRY 0x80 #endif /********************************************************************************************************* ** 函数名称: __ifArpSearch @@ -46,6 +49,7 @@ ** ipaddr ip ** ethaddr 以太网地址 ** iStatic 静态 ? +** iStrict 强绑定 ? ** ipaddr_s 比较 ip ** netif_s 保存网络接口 ** flags_s 保存 flags @@ -58,6 +62,7 @@ static INT __ifArpSearch (struct netif *netif, ip4_addr_t *ipaddr, struct eth_addr *ethaddr, INT iStatic, + INT iStrict, ip4_addr_t *ipaddr_s, struct netif **netif_s, int *flags_s, @@ -67,6 +72,9 @@ static INT __ifArpSearch (struct netif *netif, *netif_s = netif; if (iStatic) { *flags_s = ATF_INUSE | ATF_COM | ATF_PERM; + if (iStrict) { + *flags_s |= ATF_STRICT; + } } else { *flags_s = ATF_INUSE | ATF_COM; } @@ -83,6 +91,7 @@ static INT __ifArpSearch (struct netif *netif, ** ipaddr ip ** ethaddr 以太网地址 ** iStatic 静态 ? +** iStrict 强绑定 ? ** puiCount 累加变量 ** 输 出 : 0: 继续遍历 1: 退出遍历 ** 全局变量: @@ -92,6 +101,7 @@ static INT __ifArpCount (struct netif *netif, ip4_addr_t *ipaddr, struct eth_addr *ethaddr, INT iStatic, + INT iStrict, UINT *puiCount) { (*puiCount)++; @@ -104,6 +114,7 @@ static INT __ifArpCount (struct netif *netif, ** ipaddr ip ** ethaddr 以太网地址 ** iStatic 静态 ? +** iStrict 强绑定 ? ** parplst 缓冲列表 ** 输 出 : 0: 继续遍历 1: 退出遍历 ** 全局变量: @@ -113,6 +124,7 @@ static INT __ifArpWalk (struct netif *netif, ip4_addr_t *ipaddr, struct eth_addr *ethaddr, INT iStatic, + INT iStrict, struct arpreq_list *parplst) { if (parplst->arpl_num < parplst->arpl_bcnt) { @@ -126,6 +138,9 @@ static INT __ifArpWalk (struct netif *netif, netif_get_name(netif, parpreq->arp_dev); if (iStatic) { parpreq->arp_flags = ATF_INUSE | ATF_COM | ATF_PERM; + if (iStrict) { + parpreq->arp_flags |= ATF_STRICT; + } } else { parpreq->arp_flags = ATF_INUSE | ATF_COM; } @@ -162,6 +177,9 @@ static INT __ifArpSet (const struct arpreq *parpreq) } if (parpreq->arp_flags & ATF_PERM) { flags = ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY; + if (parpreq->arp_flags & ATF_STRICT) { + flags |= ETHARP_FLAG_STRICT_ENTRY; + } } else { flags = ETHARP_FLAG_TRY_HARD; } @@ -181,7 +199,7 @@ static INT __ifArpSet (const struct arpreq *parpreq) err = netifapi_arp_update(netif, &ipaddr, ðaddr, flags); if (err) { - _ErrorHandle(EINVAL); + _ErrorHandle(err_to_errno(err)); return (PX_ERROR); } @@ -243,9 +261,13 @@ static INT __ifArpDel (const struct arpreq *parpreq) } ipaddr.addr = ((struct sockaddr_in *)&parpreq->arp_pa)->sin_addr.s_addr; - err = netifapi_arp_remove(&ipaddr, NETIFAPI_ARP_PERM); + if (parpreq->arp_flags & ATF_PERM) { + err = netifapi_arp_remove(&ipaddr, NETIFAPI_ARP_PERM); + } else { + err = netifapi_arp_remove(&ipaddr, NETIFAPI_ARP_COM); + } if (err) { - _ErrorHandle(EINVAL); + _ErrorHandle(err_to_errno(err)); return (PX_ERROR); } diff --git a/SylixOS/net/lwip/proc/lwip_proc.c b/SylixOS/net/lwip/proc/lwip_proc.c index aa21c60..3bab7d8 100644 --- a/SylixOS/net/lwip/proc/lwip_proc.c +++ b/SylixOS/net/lwip/proc/lwip_proc.c @@ -3101,6 +3101,7 @@ static ssize_t __procFsNetIfInet6Read (PLW_PROCFS_NODE p_pfsn, ** ipaddr arp ip 地址 ** ethaddr arp mac 地址 ** iIsStatic 是否为静态转换关系 +** iIsStrict 是否为强绑定 ** pcBuffer 缓冲 ** stTotalSize 缓冲区大小 ** pstOft 当前偏移量 @@ -3112,6 +3113,7 @@ static INT __procFsNetArpPrint (struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, INT iIsStatic, + INT iIsStrict, PCHAR pcBuffer, size_t stTotalSize, size_t *pstOft) @@ -3120,7 +3122,7 @@ static INT __procFsNetArpPrint (struct netif *netif, CHAR cIfName[NETIF_NAMESIZE]; *pstOft = bnprintf(pcBuffer, stTotalSize, *pstOft, - "%-4s %-16s %02x:%02x:%02x:%02x:%02x:%02x %s\n", + "%-4s %-16s %02x:%02x:%02x:%02x:%02x:%02x %s%s\n", netif_get_name(netif, cIfName), ipaddr_ntoa_r(ipaddr, cBuffer, INET_ADDRSTRLEN), ethaddr->addr[0], @@ -3129,7 +3131,8 @@ static INT __procFsNetArpPrint (struct netif *netif, ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5], - (iIsStatic) ? "static" : "dynamic"); + (iIsStatic) ? "static" : "dynamic", + (iIsStrict) ? "(s)" : ""); return (ERROR_NONE); } diff --git a/SylixOS/net/lwip/src/api/netifapi.c b/SylixOS/net/lwip/src/api/netifapi.c index 79c4a9d..728bf82 100644 --- a/SylixOS/net/lwip/src/api/netifapi.c +++ b/SylixOS/net/lwip/src/api/netifapi.c @@ -203,7 +203,7 @@ netifapi_arp_remove(const ip4_addr_t *ipaddr, enum netifapi_arp_entry type) #if ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING LOCK_TCPIP_CORE(); - err = etharp_remove_static_entry(ipaddr); + err = etharp_remove_static_entry(ipaddr, type == NETIFAPI_ARP_COM ? 1 : 0 /* SylixOS Add force delete */); UNLOCK_TCPIP_CORE(); #else /* @todo add new vars to struct netifapi_msg and create a 'do' func */ diff --git a/SylixOS/net/lwip/src/core/ipv4/etharp.c b/SylixOS/net/lwip/src/core/ipv4/etharp.c index 930717e..c2463e4 100644 --- a/SylixOS/net/lwip/src/core/ipv4/etharp.c +++ b/SylixOS/net/lwip/src/core/ipv4/etharp.c @@ -100,10 +100,37 @@ struct etharp_entry { struct eth_addr ethaddr; u16_t ctime; u8_t state; + +#ifdef SYLIXOS /* SylixOS Add strict binding mode */ + u8_t strict; /* This is a strict binding */ + u8_t conflict; /* This entry confilct with strict binding */ +#endif /* SYLIXOS */ }; static struct etharp_entry arp_table[ARP_TABLE_SIZE]; +#ifdef SYLIXOS /* SylixOS Add strict binding mode */ +static int arp_strict_cnt = 0; + +/* Make entry strict binding */ +#define ETHARP_MAKE_STRICT(i) \ + { \ + if (!arp_table[i].strict) { \ + arp_table[i].strict = 1; \ + arp_strict_cnt++; \ + } \ + } + +/* Clear entry strict binding */ +#define ETHARP_CLEAR_STRICT(i) \ + { \ + if (arp_table[i].strict) { \ + arp_table[i].strict = 0; \ + arp_strict_cnt--; \ + } \ + } +#endif /* SYLIXOS */ + #if !LWIP_NETIF_HWADDRHINT static netif_addr_idx_t etharp_cached_entry; #endif /* !LWIP_NETIF_HWADDRHINT */ @@ -116,6 +143,10 @@ static netif_addr_idx_t etharp_cached_entry; #define ETHARP_FLAG_STATIC_ENTRY 4 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ +#ifdef SYLIXOS /* SylixOS Add strict binding mode */ +#define ETHARP_FLAG_STRICT_ENTRY 0x80 /* SylixOS Add strict IP MAC binding */ +#endif + #if LWIP_NETIF_HWADDRHINT #define ETHARP_SET_ADDRHINT(netif, addrhint) do { if (((netif) != NULL) && ((netif)->hints != NULL)) { \ (netif)->hints->addr_hint = (addrhint); }} while(0) @@ -186,6 +217,10 @@ etharp_free_entry(int i) } /* recycle entry for re-use */ arp_table[i].state = ETHARP_STATE_EMPTY; +#ifdef SYLIXOS /* SylixOS Add strict binding mode */ + ETHARP_CLEAR_STRICT(i); + arp_table[i].conflict = 0; +#endif /* SYLIXOS */ #ifdef LWIP_DEBUG /* for debugging, clean out the complete entry */ arp_table[i].ctime = 0; @@ -239,6 +274,31 @@ etharp_tmr(void) } } +#ifdef SYLIXOS /* SylixOS Add clean same mac */ +/** + * Clean same mac IP address binding + * + * @param ethaddr Ethernet address + * @param except Excluded index + */ +static void +etharp_clean_ethaddr(struct eth_addr *ethaddr, s16_t except) +{ + s16_t i; + + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + if (i == except) { + continue; + } + if (arp_table[i].state >= ETHARP_STATE_STABLE) { + if (eth_addr_cmp(&arp_table[i].ethaddr, ethaddr)) { + etharp_free_entry(i); + } + } + } +} +#endif /* SYLIXOS */ + /** * Search the ARP table for a matching or new entry. * @@ -256,12 +316,13 @@ etharp_tmr(void) * @param ipaddr IP address to find in ARP cache, or to add if not found. * @param flags See @ref etharp_state * @param netif netif related to this address (used for NETIF_HWADDRHINT) + * @param strict_ethaddr SylixOS Add strict binding mode. * * @return The ARP entry index that matched or is created, ERR_MEM if no * entry is found or could be recycled. */ static s16_t -etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif) +etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif, struct eth_addr *strict_ethaddr) { s16_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE; s16_t empty = ARP_TABLE_SIZE; @@ -271,6 +332,11 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif) /* its age */ u16_t age_queue = 0, age_pending = 0, age_stable = 0; +#ifdef SYLIXOS + s16_t same = -1; + u8_t has_strict = 0; /* SylixOS Add strict binding mode */ +#endif + LWIP_UNUSED_ARG(netif); /** @@ -306,7 +372,16 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif) ) { LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %d\n", (int)i)); /* found exact IP address match, simply bail out */ +#ifdef SYLIXOS /* SylixOS Add strict binding support */ + if (!strict_ethaddr || !arp_strict_cnt) { + return i; /* Return immediately */ + } else { + same = i; + goto next; /* Need check strict binding conflict */ + } +#else /* SYLIXOS */ return i; +#endif /* !SYLIXOS */ } /* pending entry? */ if (state == ETHARP_STATE_PENDING) { @@ -337,6 +412,13 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif) age_stable = arp_table[i].ctime; } } +#ifdef SYLIXOS /* SylixOS Add strict binding support */ + else if (strict_ethaddr && arp_table[i].strict && !has_strict) { + if (eth_addr_cmp(&arp_table[i].ethaddr, strict_ethaddr)) { + has_strict = 1; + } + } +#endif /* SYLIXOS */ } } } @@ -350,6 +432,31 @@ etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif *netif) return (s16_t)ERR_MEM; } +#ifdef SYLIXOS /* SylixOS Add strict binding mode */ +next: + if (same >= 0) { + if (!has_strict) { + for (i = same + 1; i < ARP_TABLE_SIZE; ++i) { /* Check the remaining mac bindings */ + if (arp_table[i].strict && eth_addr_cmp(&arp_table[i].ethaddr, strict_ethaddr)) { + has_strict = 1; /* Has mac conflict */ + break; + } + } + } + if (has_strict) { + arp_table[same].conflict = 1; /* This entry has confilct with strict binding do not queue packet */ + return (s16_t)ERR_USE; + } else { + arp_table[same].conflict = 0; /* Normal entry */ + return same; + } + } else { /* Traversed */ + if (has_strict) { + return (s16_t)ERR_USE; + } + } +#endif /* SYLIXOS */ + /* b) choose the least destructive entry to recycle: * 1) empty entry * 2) oldest stable entry @@ -448,7 +555,7 @@ etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct et return ERR_ARG; } /* find or create ARP entry */ - i = etharp_find_entry(ipaddr, flags, netif); + i = etharp_find_entry(ipaddr, flags, netif, ethaddr /* SylixOS Add strict binding mode */); /* bail out if no entry could be found */ if (i < 0) { return (err_t)i; @@ -458,6 +565,12 @@ etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct et if (flags & ETHARP_FLAG_STATIC_ENTRY) { /* record static type */ arp_table[i].state = ETHARP_STATE_STATIC; +#ifdef SYLIXOS /* SylixOS Add strict binding mode */ + if (flags & ETHARP_FLAG_STRICT_ENTRY) { + ETHARP_MAKE_STRICT(i); + etharp_clean_ethaddr(ethaddr, i); /* SylixOS Strict binding need clean mac */ + } +#endif /* SYLIXOS */ } else if (arp_table[i].state == ETHARP_STATE_STATIC) { /* found entry is a static type, don't overwrite it */ return ERR_VAL; @@ -466,6 +579,9 @@ etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct et { /* mark it stable */ arp_table[i].state = ETHARP_STATE_STABLE; +#ifdef SYLIXOS /* SylixOS Add strict binding mode */ + ETHARP_CLEAR_STRICT(i); +#endif } /* record network interface */ @@ -539,7 +655,7 @@ etharp_add_static_entry(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr) * ERR_ARG: entry wasn't a static entry but a dynamic one */ err_t -etharp_remove_static_entry(const ip4_addr_t *ipaddr) +etharp_remove_static_entry(const ip4_addr_t *ipaddr, u8_t force /* SylixOS Add force delete */) { s16_t i; LWIP_ASSERT_CORE_LOCKED(); @@ -547,13 +663,14 @@ etharp_remove_static_entry(const ip4_addr_t *ipaddr) ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); /* find or create ARP entry */ - i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, NULL); + i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, NULL, NULL); /* bail out if no entry could be found */ if (i < 0) { return (err_t)i; } - if (arp_table[i].state != ETHARP_STATE_STATIC) { + /* SylixOS Add force delete */ + if (!force && arp_table[i].state != ETHARP_STATE_STATIC) { /* entry wasn't a static entry, cannot remove it */ return ERR_ARG; } @@ -603,7 +720,7 @@ etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr, LWIP_UNUSED_ARG(netif); - i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, netif); + i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, netif, NULL); if ((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) { *eth_ret = &arp_table[i].ethaddr; *ip_ret = &arp_table[i].ipaddr; @@ -980,7 +1097,7 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q) } /* find entry in ARP cache, ask to create entry if queueing packet */ - i_err = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD, netif); + i_err = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD, netif, NULL); /* could not find or create entry? */ if (i_err < 0) { @@ -1030,6 +1147,12 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q) } } +#ifdef SYLIXOS /* Confilct strict entry do not queue packet */ + if (arp_table[i].conflict) { + return ERR_OK; /* Return OK? */ + } +#endif /* SYLIXOS */ + /* packet given? */ LWIP_ASSERT("q != NULL", q != NULL); /* stable entry? */ @@ -1275,7 +1398,7 @@ etharp_traversal(struct netif *netif, (arp_table[i].state == ETHARP_STATE_STATIC)) { if ((!netif) || (arp_table[i].netif == netif)) { if (callback(arp_table[i].netif, &arp_table[i].ipaddr, &arp_table[i].ethaddr, - (arp_table[i].state == ETHARP_STATE_STATIC), + (arp_table[i].state == ETHARP_STATE_STATIC), (int)arp_table[i].strict, arg0, arg1, arg2, arg3, arg4, arg5)) { break; } |