diff options
| author | Qiuwen Lu <[email protected]> | 2016-11-04 19:36:40 +0800 |
|---|---|---|
| committer | Qiuwen Lu <[email protected]> | 2016-11-04 19:36:40 +0800 |
| commit | 753522085286884e281260fbed1ee0d13dc0b519 (patch) | |
| tree | fcc1046ab066d7b553b0e4a667c58311a4c0ddb4 | |
| parent | df63f60821b8b2dd8416c92a932174f06b0b79f8 (diff) | |
重构邻居子系统实现,接口与MR3类似,增加对应的单元测试代码。
| -rw-r--r-- | stack/include/sk_neigh.h | 128 | ||||
| -rw-r--r-- | stack/src/neigh.c | 348 | ||||
| -rw-r--r-- | test/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | test/TestStackNeigh.cc | 93 |
4 files changed, 319 insertions, 254 deletions
diff --git a/stack/include/sk_neigh.h b/stack/include/sk_neigh.h index 934ac9e..bb418f6 100644 --- a/stack/include/sk_neigh.h +++ b/stack/include/sk_neigh.h @@ -1,82 +1,48 @@ -#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <rte_rwlock.h>
-#include <rte_atomic.h>
-#include <rte_timer.h>
-#include <rte_ether.h>
-
-#define SK_NEIGH_MAX_HDR 0x60
-
-struct sk_neigh_table
-{
- struct rte_timer * event_timer;
- struct rte_hash * neigh_tbl;
- rte_rwlock_t neigh_tbl_lock;
-};
-
-struct sk_dest_info
-{
- uint16_t mtu;
- uint8_t l2_len;
- uint8_t l3_len;
- uint8_t hdr[SK_NEIGH_MAX_HDR];
-};
-
-#define NUD_INCOMPLETE 0x01
-#define NUD_REACHABLE 0x02
-#define NUD_STALE 0x04
-#define NUD_DELAY 0x08
-#define NUD_PROBE 0x10
-#define NUD_FAILED 0x20
-#define NUD_NOARP 0x40
-#define NUD_PERMANENT 0x80
-#define NUD_NONE 0x00
-
-#define NUD_IN_TIMER ( NUD_INCOMPLETE | NUD_REACHABLE | NUD_DELAY | NUD_PROBE )
-#define NUD_VALID ( NUD_PERMANENT | NUD_NOARP | NUD_REACHABLE | NUD_PROBE | NUD_STALE | NUD_DELAY )
-#define NUD_CONNECTED ( NUD_PERMANENT | NUD_NOARP | NUD_REACHABLE )
-
-struct sk_neighbour
-{
- // ���ü���
- rte_atomic16_t refcnt;
- // ������
- rte_rwlock_t rwlock;
- // ��ʱ��
- struct rte_timer timer;
- // ״̬
- unsigned int state;
- // ��Ч��־λ
- unsigned int dead;
- // ������ʱ��
- unsigned int update;
- // �����豸
- struct sk_dev_desc * dev;
- // ��ѯ����
- struct in_addr in_addr;
- // ��ѯ���
- struct ether_addr ether_addr;
- // ���������Ϣ
- struct sk_dest_info dest_info;
-};
-
-int neigh_update(struct sk_neighbour * neigh, const struct ether_addr * lladdr,
- uint8_t state, uint32_t flags);
-
-int neigh_event_send(struct sk_neighbour * neigh, struct rte_mbuf * mbuf);
-
-struct sk_neighbour * neigh_create(struct sk_neigh_table * tbl,
- struct in_addr in_addr, struct sk_dev_desc * dev);
-
-struct sk_neighbour * neigh_lookup(struct sk_neigh_table * tbl,
- const void * pkey, int hold);
-
-int neigh_tbl_init(struct sk_neigh_table * tbl, const char * symbol, unsigned int nr_entries);
-
-#ifdef __cplusplus
-}
+#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include <sk_device.h> + +struct neighbour; +TAILQ_HEAD(neighbour_list, neighbour); + +struct neighbour_manager +{ + /* ��д�� */ + rte_rwlock_t rwlock; + /* ��ѯ��ϣ�� */ + struct rte_hash * table; + /* ����ѯ������� */ + struct neighbour_list in_none_list; + /* ����ѯ������г��ȣ�����rwlock�ı����� */ + rte_atomic16_t in_none_list_len; + /* ���������� */ + unsigned int max_entries; + /* ������ѯ������ */ + unsigned int max_queue_entries; + /* �����ϻ�ʱ�� */ + unsigned short t_timeout; + /* ARP����Ƶ�� */ + unsigned short t_arp_send; +}; + +int neighbour_mamanger_init(struct neighbour_manager * object, + const char * symbol, unsigned int max_entries, unsigned int max_queue_entries, + unsigned short t_timeout, unsigned int t_arp_send); + +int neighbour_mamanger_deinit(struct neighbour_manager * object); + +int neigh_create_or_update(struct neighbour_manager * object, struct in_addr in_addr, + struct ether_addr * eth_addr, struct sk_dev_info * devinfo, unsigned short en_permanent); + +int neigh_delete(struct neighbour_manager * object, struct in_addr in_addr); + +int neigh_query(struct neighbour_manager * object, struct in_addr in_addr, + struct ether_addr * out_ether_addr, struct sk_dev_info ** out_dev_info); + +#ifdef __cplusplus +} #endif
\ No newline at end of file diff --git a/stack/src/neigh.c b/stack/src/neigh.c index ac2ef3c..35345b8 100644 --- a/stack/src/neigh.c +++ b/stack/src/neigh.c @@ -11,220 +11,242 @@ #include <rte_rwlock.h> #include <rte_atomic.h> #include <rte_ether.h> -#include <rte_ip.h> #include <rte_ip_frag.h> #include <rte_timer.h> - +#include <mr_common.h> #include <sk_device.h> -#include <sk_protocol_arp.h> -#include <sk_neigh.h> -#include <rte_cycles.h> #include <rte_hash_crc.h> +#include <rte_errno.h> +#include <errno.h> +#include <assert.h> +#include <sk_neigh.h> -#define __IP_VERSION_IHL(version, len) (version << 4 | len << 0) -#define __IP_TTL 75 - -// �����㱨��ͷ -static inline size_t __neigh_fill_ether_hdr(uint8_t * hdr, const struct ether_addr * src_addr, - const struct ether_addr * dst_addr, const uint16_t next_layer_type) +enum neigh_state { - struct ether_hdr * ether_hdr = (struct ether_hdr *)hdr; - ether_addr_copy(src_addr, ðer_hdr->s_addr); - ether_addr_copy(dst_addr, ðer_hdr->d_addr); - ether_hdr->ether_type = htons(next_layer_type); - return sizeof(struct ether_hdr); -} - -// ������㱨��ͷ -static inline size_t __neigh_fill_ipv4_hdr(uint8_t * hdr, const struct in_addr * src_addr, - const struct in_addr * dst_addr, uint16_t total_len, uint16_t pid, uint8_t next_proto) + NEIGH_IN_NONE = 0, + NEIGH_IN_COMPLETE = 1, + NEIGH_IN_USE = 2, + NEIGH_IN_TIMEOUT = 3, + NEIGH_IN_DEAD = 4 +}; + +/* Neighbour Table Object Rule */ +struct neighbour { - struct ipv4_hdr * ip_hdr = (struct ipv4_hdr *)hdr; - - ip_hdr->version_ihl = __IP_VERSION_IHL(4, sizeof(struct ipv4_hdr) / 4); - ip_hdr->type_of_service = 0; - ip_hdr->total_length = htons(total_len); - ip_hdr->packet_id = htons(pid); - ip_hdr->fragment_offset = 0; - ip_hdr->time_to_live = __IP_TTL; - ip_hdr->next_proto_id = next_proto; - ip_hdr->hdr_checksum = 0; - - ip_hdr->src_addr = src_addr->s_addr; - ip_hdr->dst_addr = dst_addr->s_addr; - return sizeof(struct ipv4_hdr); -} + /* ������ */ + TAILQ_ENTRY(neighbour) next; + /* IP��ַ */ + struct in_addr in_addr; + /* Ŀ��MAC��ַ */ + struct ether_addr eth_addr; + /* �豸������ */ + struct sk_dev_info * dev_info; + /* ����״̬ */ + enum neigh_state state; + /* ת�뵱ǰ״̬��ʱ�� */ + time_t t_start_state; + /* �ϴη���ARP�����ʱ�� */ + time_t t_last_request; + /* �ϴ��յ�ARPӦ���ʱ�� */ + time_t t_last_update; + /* ���ñ�־λ */ + unsigned short en_permanent; +}; + +int neighbour_mamanger_init(struct neighbour_manager * object, + const char * symbol, unsigned int max_entries, unsigned int max_queue_entries, + unsigned short t_timeout, unsigned int t_arp_send) +{ + int ret = 0; -static inline void neigh_fill_destinfo(struct sk_neighbour * neigh) -{ - struct sk_dest_info * dest_info = &neigh->dest_info; - size_t ret; - - ret = __neigh_fill_ether_hdr(dest_info->hdr, - &neigh->dev->dev_info->mac_addr, &neigh->ether_addr, - ETHER_TYPE_IPv4); - neigh->dest_info.l2_len = ret; - - ret = __neigh_fill_ipv4_hdr(dest_info->hdr + ret, - &neigh->dev->dev_info->in_addr, - &neigh->in_addr, 0, 0, 0); - neigh->dest_info.l3_len = ret; - return; -} + char tbsymbol[MR_SYMBOL_MAX]; + snprintf(tbsymbol, sizeof(tbsymbol), "NEIGH_%s", symbol); -static void neigh_destory(struct sk_neighbour * neigh) -{ - return; -} + struct rte_hash_parameters hash_params = + { + .name = tbsymbol, + .entries = max_entries, + .key_len = sizeof(struct in_addr), + .hash_func = NULL, + .hash_func_init_val = 0, + }; -static void neigh_probe(struct sk_neighbour * neigh) -{ - protocol_arp_request_send(neigh->dev, neigh->in_addr); + object->table = rte_hash_create(&hash_params); + if (unlikely(object->table == NULL)) + { + MR_LOG(WARNING, STACK, "NeighbourManagerInit," + "Cannot create hash table for %s : %s", symbol, __str_errno()); + ret = -1; goto errout; + } + + TAILQ_INIT(&object->in_none_list); + rte_atomic16_init(&object->in_none_list_len); + rte_rwlock_init(&object->rwlock); + return 0; + +errout: + if (object->table != NULL) rte_hash_free(object->table); + return ret; } -static inline void neigh_hold(struct sk_neighbour * neigh) +int neighbour_mamanger_deinit(struct neighbour_manager * object) { - rte_atomic16_add(&neigh->refcnt, 1); - return; + rte_hash_free(object->table); + return 0; } -static inline void neigh_release(struct sk_neighbour * neigh) +static void __change_neigh_state(struct neighbour * neigh, enum neigh_state target_state) { - if (rte_atomic16_dec_and_test(&neigh->refcnt)) - neigh_destory(neigh); - return; + if (target_state != neigh->state) + { + neigh->state = target_state; + neigh->t_start_state = time(NULL); + } } -static struct sk_neighbour * neigh_alloc(struct sk_neigh_table * tbl, struct sk_dev_desc * dev) +static struct neighbour * __neigh_create_and_join_hash(struct neighbour_manager * object, + struct in_addr in_addr, struct ether_addr * eth_addr, + struct sk_dev_info * devinfo, unsigned short en_permanent) { - struct sk_neighbour * neigh = rte_zmalloc(NULL, sizeof(struct sk_neighbour), 0); + struct neighbour * neigh = rte_zmalloc(NULL, sizeof(struct neighbour), 0); if (unlikely(neigh == NULL)) { - MR_LOG(INFO, STACK, "NeighSystem, NeighCreate, " - "Cannot alloc memory for neighbor structure. \n"); + MR_LOG(WARNING, STACK, "Neighbour, Cannot create neigh structure : %s", __str_errno()); return NULL; } - rte_rwlock_init(&neigh->rwlock); - rte_atomic16_init(&neigh->refcnt); - neigh->state = NUD_NONE; - neigh->dead = 1; - neigh->update = rte_rdtsc(); - neigh->dev = dev; - return neigh; -} + neigh->in_addr = in_addr; + neigh->dev_info = devinfo; + neigh->en_permanent = en_permanent; + neigh->t_last_update = 0; + neigh->t_last_request = 0; + neigh->state = NEIGH_IN_NONE; - -int neigh_update(struct sk_neighbour * neigh, const struct ether_addr * lladdr, - uint8_t state, uint32_t flags) -{ - rte_rwlock_write_lock(&neigh->rwlock); - struct sk_dev_desc * dev = neigh->dev; - uint8_t old_state = neigh->state; - - if((old_state & NUD_REACHABLE) && (state & NUD_REACHABLE)) + if(eth_addr != NULL) { - ether_addr_copy(lladdr, &neigh->ether_addr); - neigh_fill_destinfo(neigh); - neigh->dead = 0; - neigh->state = state; + ether_addr_copy(eth_addr, &neigh->eth_addr); + __change_neigh_state(neigh, NEIGH_IN_USE); } - if((old_state & NUD_INCOMPLETE ) && (state & NUD_REACHABLE)) + if(en_permanent) + { + neigh->en_permanent = 1; + } + + hash_sig_t hash = rte_hash_crc(&in_addr, sizeof(in_addr), 0); + int ret = rte_hash_add_key_with_hash_data(object->table, &in_addr, hash, neigh); + if (unlikely(ret < 0)) { - ether_addr_copy(lladdr, &neigh->ether_addr); - neigh_fill_destinfo(neigh); - neigh->dead = 0; - neigh->state = state; + MR_LOG(WARNING, STACK, "Neighbour, Insert neigh to hash table failed : %s", + __str_errno()); + goto errout; } + + return neigh; - rte_rwlock_write_unlock(&neigh->rwlock); - return 0; +errout: + if (neigh) rte_free(neigh); + return NULL; } -int neigh_event_send(struct sk_neighbour * neigh, struct rte_mbuf * mbuf) +static void __neigh_update(struct neighbour * neigh, struct in_addr in_addr, + struct ether_addr * eth_addr, struct sk_dev_info * devinfo, unsigned short en_permanent) { - rte_rwlock_write_lock(&neigh->rwlock); - - if (neigh->state & (NUD_REACHABLE)) - goto out_unblock; - - if(neigh->state & NUD_NONE) + assert(neigh != NULL); + neigh->in_addr = in_addr; + neigh->en_permanent = en_permanent; + neigh->dev_info = devinfo; + + if(eth_addr != NULL) { - neigh_probe(neigh); - goto out_unblock; + ether_addr_copy(eth_addr, &neigh->eth_addr); + __change_neigh_state(neigh, NEIGH_IN_USE); } - //TODO: ����״̬������ - -out_unblock: - rte_rwlock_write_unlock(&neigh->rwlock); - return 0; + return; } -struct sk_neighbour * neigh_create(struct sk_neigh_table * tbl, - struct in_addr in_addr, struct sk_dev_desc * dev) +int neigh_create_or_update(struct neighbour_manager * object, struct in_addr in_addr, + struct ether_addr * eth_addr, struct sk_dev_info * devinfo, unsigned short en_permanent) { - struct sk_neighbour * neigh = neigh_alloc(tbl, dev); - if (unlikely(neigh == NULL)) return NULL; - - // Hashֵ��ΪIP��ַ������ֵ�����뵽Hash���� - hash_t hash = in_addr.s_addr; - rte_rwlock_write_lock(&tbl->neigh_tbl_lock); - rte_hash_add_key_with_hash(tbl->neigh_tbl, &hash, hash); - rte_rwlock_write_unlock(&tbl->neigh_tbl_lock); + rte_rwlock_write_lock(&object->rwlock); + struct neighbour * neigh = NULL; + hash_sig_t hash = rte_hash_crc(&in_addr, sizeof(in_addr), 0); + + int ret = rte_hash_lookup_with_hash_data(object->table, &in_addr, hash, (void **)&neigh); + if (ret < 0) + { + neigh = __neigh_create_and_join_hash(object, in_addr, eth_addr, devinfo, en_permanent); + } + else + { + __neigh_update(neigh, in_addr, eth_addr, devinfo, en_permanent); + } + + if (unlikely(neigh == NULL)) return -1; + if (neigh->state == NEIGH_IN_NONE) + { + TAILQ_INSERT_TAIL(&object->in_none_list, neigh, next); + rte_atomic16_inc(&object->in_none_list_len); + } + + ret = 0; goto exit; - // ���������¼�������ARP���� - neigh_event_send(neigh, NULL); - neigh_hold(neigh); - return neigh; +exit: + rte_rwlock_write_unlock(&object->rwlock); + return ret; } -struct sk_neighbour * neigh_lookup(struct sk_neigh_table * tbl, - const void * pkey, int hold) +int neigh_delete(struct neighbour_manager * object, struct in_addr in_addr) { - hash_t hash = *(uint32_t *)pkey; - struct sk_neighbour * neigh; + rte_rwlock_write_lock(&object->rwlock); + struct neighbour * neigh = NULL; - rte_rwlock_read_lock(&tbl->neigh_tbl_lock); - rte_hash_lookup_with_hash_data(tbl->neigh_tbl, &hash, hash, (void **)&neigh); - rte_rwlock_read_unlock(&tbl->neigh_tbl_lock); - - if (neigh == NULL) return NULL; + hash_sig_t hash = rte_hash_crc(&in_addr, sizeof(in_addr), 0); + int ret = rte_hash_lookup_with_hash_data(object->table, &in_addr, hash, (void **)&neigh); + if (ret < 0) goto exit; - if (hold) neigh_hold(neigh); - return neigh; + // ������IN_NONE״̬ʱ����IN_NONE�б����Ƴ� + if (neigh->state == NEIGH_IN_NONE) + { + TAILQ_REMOVE(&object->in_none_list,neigh, next); + rte_atomic16_dec(&object->in_none_list_len); + } + + rte_hash_del_key_with_hash(object->table, &in_addr, hash); + rte_free(neigh); + ret = 0; goto exit; + +exit: + rte_rwlock_write_unlock(&object->rwlock); + return ret; } -int neigh_tbl_init(struct sk_neigh_table * tbl, const char * symbol, unsigned int nr_entries) +int neigh_query(struct neighbour_manager * object, struct in_addr in_addr, + struct ether_addr * out_ether_addr, struct sk_dev_info ** out_dev_info) { - char hash_tbl_symbol[MR_SYMBOL_MAX]; - snprintf(hash_tbl_symbol, sizeof(hash_tbl_symbol), "NTB-%s", symbol); - - struct rte_hash_parameters hash_params = - { - .name = hash_tbl_symbol, - .entries = nr_entries, - .key_len = sizeof(uint32_t), - .hash_func = rte_hash_crc, - .hash_func_init_val = 0, - }; + struct neighbour * neigh = NULL; + + rte_rwlock_read_lock(&object->rwlock); + hash_sig_t hash = rte_hash_crc(&in_addr, sizeof(in_addr), 0); + int ret = rte_hash_lookup_with_hash_data(object->table, &in_addr, hash, (void **)&neigh); - tbl->neigh_tbl = rte_hash_create(&hash_params); - if (unlikely(tbl == NULL)) + // û�鵽 + if (ret < 0) goto exit; + + // ����״̬��Ϣ��ȫ���������ṩ��ѯ + if (neigh->state == NEIGH_IN_NONE || + neigh->state == NEIGH_IN_COMPLETE || + neigh->state == NEIGH_IN_DEAD) { - MR_LOG(WARNING, STACK, "NeighSystem, NeighTblInit, " - "Create hash table %s failed(for NeighTable %s): %s. \n", - hash_tbl_symbol, symbol, rte_strerror(rte_errno)); - return -1; + ret = -EFAULT; goto exit; } + + ether_addr_copy(&neigh->eth_addr, out_ether_addr); + *out_dev_info = neigh->dev_info; + ret = 0; goto exit; - rte_rwlock_init(&tbl->neigh_tbl_lock); - return 0; -} - -int neigh_tbl_deinit(struct sk_neigh_table * tbl) -{ - rte_hash_reset(tbl->neigh_tbl); - return 0; +exit: + rte_rwlock_read_unlock(&object->rwlock); + return ret; }
\ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 03898c5..8cf7596 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -30,5 +30,5 @@ set(TEST_LINK_LIBRARIES ${DPDK_LIBRARY} gtest) # add_executable(TestVMan TestVMan.cc Unittest.cc)
# target_link_libraries(TestVMan ${TEST_LINK_LIBRARIES} core)
-# add_executable(TestNeigh TestStackNeigh.cc Unittest.cc)
-# target_link_libraries(TestNeigh ${TEST_LINK_LIBRARIES} stack)
\ No newline at end of file +add_executable(TestNeigh TestStackNeigh.cc Unittest.cc)
+target_link_libraries(TestNeigh ${TEST_LINK_LIBRARIES} stack)
\ No newline at end of file diff --git a/test/TestStackNeigh.cc b/test/TestStackNeigh.cc index 36fab6d..711c101 100644 --- a/test/TestStackNeigh.cc +++ b/test/TestStackNeigh.cc @@ -1,30 +1,107 @@ #include <gtest/gtest.h> #include <sk_device.h> -#include <sk_neigh.h> #include <netinet/in.h> +#include <sk_neigh.h> +#include <arpa/inet.h> class TCStackNeigh : public ::testing::Test { protected: - struct sk_neigh_table neigh_tbl_; - struct sk_dev_desc neigh_dev_desc_; + struct neighbour_manager nbl_object_; + struct sk_dev_info dev_info_; virtual void SetUp() { - int ret = neigh_tbl_init(&neigh_tbl_, "TestNeigh", 10000); - neigh_dev_desc_.dev_info = new sk_dev_info; + int ret = neighbour_mamanger_init(&nbl_object_, "TestNeighbour", + 1024, 8, 0, 0); ASSERT_EQ(ret, 0); } virtual void TearDown() { + int ret = neighbour_mamanger_deinit(&nbl_object_); + ASSERT_EQ(ret, 0); } }; -TEST_F(TCStackNeigh, TestNeighCreate) +TEST_F(TCStackNeigh, CreateAndQuery) { + int ret = 0; struct in_addr _in_addr; - _in_addr.s_addr = 1000000; - neigh_create(&neigh_tbl_, _in_addr, &neigh_dev_desc_); + inet_pton(AF_INET, "192.168.11.101", &_in_addr); + struct ether_addr _ether_addr = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; + + ret = neigh_create_or_update(&nbl_object_, + _in_addr, &_ether_addr, &dev_info_, 1); + + ASSERT_EQ(ret, 0); + + struct ether_addr _ether_addr_query; + struct sk_dev_info * _dev_info_query; + + ret = neigh_query(&nbl_object_, _in_addr, &_ether_addr_query, + &_dev_info_query); + + ASSERT_EQ(ret, 0); + EXPECT_EQ(is_same_ether_addr(&_ether_addr_query, &_ether_addr), 1); + EXPECT_EQ(_dev_info_query, &dev_info_); +} + +TEST_F(TCStackNeigh, CreateAndUpdate) +{ + int ret = 0; + struct in_addr _in_addr; + inet_pton(AF_INET, "192.168.11.101", &_in_addr); + struct ether_addr _ether_addr = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; + + ret = neigh_create_or_update(&nbl_object_, + _in_addr, &_ether_addr, &dev_info_, 1); + + ASSERT_EQ(ret, 0); + + struct ether_addr _ether_addr_query; + struct sk_dev_info * _dev_info_query; + + ret = neigh_query(&nbl_object_, _in_addr, &_ether_addr_query, + &_dev_info_query); + + ASSERT_EQ(ret, 0); + EXPECT_EQ(is_same_ether_addr(&_ether_addr_query, &_ether_addr), 1); + EXPECT_EQ(_dev_info_query, &dev_info_); + + struct ether_addr _ether_addr_update = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + ret = neigh_create_or_update(&nbl_object_, _in_addr, &_ether_addr_update, + &dev_info_, 1); + + ASSERT_EQ(ret, 0); + + ret = neigh_query(&nbl_object_, _in_addr, &_ether_addr_query, &_dev_info_query); + ASSERT_EQ(ret, 0); + EXPECT_EQ(is_same_ether_addr(&_ether_addr_query, &_ether_addr_update), 1); + EXPECT_EQ(_dev_info_query, &dev_info_); +} + +TEST_F(TCStackNeigh, CreateAndDelete) +{ + int ret = 0; + struct in_addr _in_addr; + inet_pton(AF_INET, "192.168.11.101", &_in_addr); + struct ether_addr _ether_addr = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; + + ret = neigh_create_or_update(&nbl_object_, + _in_addr, &_ether_addr, &dev_info_, 1); + + ASSERT_EQ(ret, 0); + + ret = neigh_delete(&nbl_object_, _in_addr); + ASSERT_EQ(ret, 0); + + struct ether_addr _ether_addr_query; + struct sk_dev_info * _dev_info_query; + + ret = neigh_query(&nbl_object_, _in_addr, &_ether_addr_query, + &_dev_info_query); + + ASSERT_LE(ret, 0); }
\ No newline at end of file |
