summaryrefslogtreecommitdiffstatsabout
path: root/SylixOS
diff options
context:
space:
mode:
authorHanhui <hanhui@acoinfo.com>2020-09-29 10:02:27 (GMT)
committer Hanhui <hanhui@acoinfo.com>2020-09-29 10:02:27 (GMT)
commit6bdb7542d4add740326d0ca005124def7c4d014c (patch)
treef013e855a22e7c8d39af97f7e24ba53ad2b2b5ac /SylixOS
parent8be77112f396363a45f1250dbb16881cb627da98 (diff)
downloadlibsylixos-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.h1
-rw-r--r--SylixOS/include/network/lwip/etharp.h2
-rw-r--r--SylixOS/include/network/lwip/netifapi.h3
-rw-r--r--SylixOS/net/lwip/lwip_arpctl.c28
-rw-r--r--SylixOS/net/lwip/proc/lwip_proc.c7
-rw-r--r--SylixOS/net/lwip/src/api/netifapi.c2
-rw-r--r--SylixOS/net/lwip/src/core/ipv4/etharp.c139
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, &ethaddr, 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;
}