diff options
author | imarom <imarom@cisco.com> | 2016-12-12 19:26:24 +0200 |
---|---|---|
committer | imarom <imarom@cisco.com> | 2016-12-12 19:26:24 +0200 |
commit | 0c45815234abbb79b147b8093eb19e274ee65f52 (patch) | |
tree | a604b3865f201e1fe841bca3a10e8f86e3248186 /src | |
parent | af9f439b2bf768f9168cecac2488b4c718ab783f (diff) |
grat ARP
Signed-off-by: imarom <imarom@cisco.com>
Diffstat (limited to 'src')
-rwxr-xr-x | src/common/Network/Packet/MacAddress.h | 2 | ||||
-rw-r--r-- | src/main_dpdk.cpp | 25 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_general.cpp | 4 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.cpp | 13 | ||||
-rw-r--r-- | src/stateless/cp/trex_stateless_port.h | 6 | ||||
-rw-r--r-- | src/stateless/messaging/trex_stateless_messaging.cpp | 5 | ||||
-rw-r--r-- | src/stateless/messaging/trex_stateless_messaging.h | 17 | ||||
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_core.cpp | 16 | ||||
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_core.h | 2 | ||||
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_port_mngr.cpp | 86 | ||||
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_port_mngr.h | 55 | ||||
-rw-r--r-- | src/trex_port_attr.cpp | 9 | ||||
-rwxr-xr-x | src/trex_port_attr.h | 6 | ||||
-rw-r--r-- | src/utl_ip.cpp | 20 | ||||
-rw-r--r-- | src/utl_ip.h | 31 |
15 files changed, 236 insertions, 61 deletions
diff --git a/src/common/Network/Packet/MacAddress.h b/src/common/Network/Packet/MacAddress.h index 9bd3eae1..924f774e 100755 --- a/src/common/Network/Packet/MacAddress.h +++ b/src/common/Network/Packet/MacAddress.h @@ -47,7 +47,7 @@ public: a5); }; - MacAddress(uint8_t macAddr[ETHER_ADDR_LEN]) + MacAddress(const uint8_t macAddr[ETHER_ADDR_LEN]) { set(macAddr[0], macAddr[1], diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index a01d57a2..03c41431 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -3153,11 +3153,6 @@ void CGlobalTRex::pre_test() { // If we got src MAC for port in global config, take it, otherwise use src MAC from DPDK uint8_t port_macs[m_max_ports][ETHER_ADDR_LEN]; for (int port_id = 0; port_id < m_max_ports; port_id++) { - uint8_t empty_mac[ETHER_ADDR_LEN] = {0,0,0,0,0,0}; - if (! memcmp( CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src, empty_mac, ETHER_ADDR_LEN)) { - rte_eth_macaddr_get(port_id, - (struct ether_addr *)&CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src); - } memcpy(port_macs[port_id], CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src, ETHER_ADDR_LEN); } @@ -3200,16 +3195,9 @@ void CGlobalTRex::pre_test() { } else { resolve_needed = false; } - if (! memcmp( CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src, empty_mac, ETHER_ADDR_LEN)) { - rte_eth_macaddr_get(port_id, - (struct ether_addr *)&CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src); - need_grat_arp[port_id] = true; - } else { - // If we got src MAC from config file, do not send gratuitous ARP for it - // (for compatibility with old behaviour) - need_grat_arp[port_id] = false; - } - + + need_grat_arp[port_id] = CGlobalInfo::m_options.m_ip_cfg[port_id].get_ip() != 0; + pretest.add_ip(port_id, CGlobalInfo::m_options.m_ip_cfg[port_id].get_ip() , CGlobalInfo::m_options.m_ip_cfg[port_id].get_vlan() , CGlobalInfo::m_options.m_mac_addr[port_id].u.m_mac.src); @@ -4880,7 +4868,14 @@ bool CPhyEthIF::Create(uint8_t portid) { m_last_tx_pps = 0.0; m_port_attr = g_trex.m_drv->create_port_attr(portid); + /* set src MAC addr */ + uint8_t empty_mac[ETHER_ADDR_LEN] = {0,0,0,0,0,0}; + if (! memcmp( CGlobalInfo::m_options.m_mac_addr[m_port_id].u.m_mac.src, empty_mac, ETHER_ADDR_LEN)) { + rte_eth_macaddr_get(m_port_id, + (struct ether_addr *)&CGlobalInfo::m_options.m_mac_addr[m_port_id].u.m_mac.src); + } + /* set src IPv4 */ uint32_t src_ipv4 = CGlobalInfo::m_options.m_ip_cfg[m_port_id].get_ip(); if (src_ipv4) { m_port_attr->set_src_ipv4(src_ipv4); diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp index 3d541fe5..5c397fcd 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp @@ -368,8 +368,10 @@ TrexRpcCmdSetPortAttr::parse_ipv4(const Json::Value &msg, uint8_t port_id, Json: ss << "invalid IPv4 address: '" << ipv4_str << "'"; generate_parse_err(result, ss.str()); } + + TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); + port->set_src_ipv4(ipv4_addr); - get_stateless_obj()->get_platform_api()->getPortAttrObj(port_id)->set_src_ipv4(ipv4_addr); return (0); } diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp index 7edf1a31..057f6521 100644 --- a/src/stateless/cp/trex_stateless_port.cpp +++ b/src/stateless/cp/trex_stateless_port.cpp @@ -987,6 +987,19 @@ TrexStatelessPort::get_rx_queue_pkts() { return reply.wait_for_reply(); } + +void +TrexStatelessPort::set_src_ipv4(uint32_t ipv4) { + + getPortAttrObj()->set_src_ipv4(ipv4); + + CManyIPInfo src_addr; + src_addr.insert(COneIPv4Info(ipv4, 0, getPortAttrObj()->get_src_mac(), m_port_id)); + + TrexStatelessRxUpdateSrcAddr *msg = new TrexStatelessRxUpdateSrcAddr(m_port_id, src_addr); + send_message_to_rx( (TrexStatelessCpToRxMsgBase *)msg ); +} + Json::Value TrexStatelessPort::rx_features_to_json() { static MsgReply<Json::Value> reply; diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h index 74ab17f1..3ae74f5a 100644 --- a/src/stateless/cp/trex_stateless_port.h +++ b/src/stateless/cp/trex_stateless_port.h @@ -400,6 +400,12 @@ public: const RXPacketBuffer *get_rx_queue_pkts(); /** + * sets an IPv4 source address + * + */ + void set_src_ipv4(uint32_t ipv4); + + /** * generate a JSON describing the status * of the RX features * diff --git a/src/stateless/messaging/trex_stateless_messaging.cpp b/src/stateless/messaging/trex_stateless_messaging.cpp index 17acb21e..dc656e67 100644 --- a/src/stateless/messaging/trex_stateless_messaging.cpp +++ b/src/stateless/messaging/trex_stateless_messaging.cpp @@ -316,3 +316,8 @@ TrexStatelessRxFeaturesToJson::handle(CRxCoreStateless *rx_core) { return true; } +bool +TrexStatelessRxUpdateSrcAddr::handle(CRxCoreStateless *rx_core) { + rx_core->get_rx_port_mngr(m_port_id).update_src_addr(m_src_addr); + return true; +} diff --git a/src/stateless/messaging/trex_stateless_messaging.h b/src/stateless/messaging/trex_stateless_messaging.h index 79a6bf08..5f00c244 100644 --- a/src/stateless/messaging/trex_stateless_messaging.h +++ b/src/stateless/messaging/trex_stateless_messaging.h @@ -27,6 +27,7 @@ limitations under the License. #include "trex_exception.h" #include "trex_stateless_rx_defs.h" #include "os_time.h" +#include "utl_ip.h" class TrexStatelessDpCore; class CRxCoreStateless; @@ -568,6 +569,22 @@ private: }; +class TrexStatelessRxUpdateSrcAddr : public TrexStatelessCpToRxMsgBase { +public: + TrexStatelessRxUpdateSrcAddr(uint8_t port_id, + const CManyIPInfo &src_addr) { + + m_port_id = port_id; + m_src_addr = src_addr; + } + + virtual bool handle(CRxCoreStateless *rx_core); + +private: + uint8_t m_port_id; + CManyIPInfo m_src_addr; +}; + /** * a request from RX core to dump to Json the RX features */ diff --git a/src/stateless/rx/trex_stateless_rx_core.cpp b/src/stateless/rx/trex_stateless_rx_core.cpp index 9898e8b9..31fef68f 100644 --- a/src/stateless/rx/trex_stateless_rx_core.cpp +++ b/src/stateless/rx/trex_stateless_rx_core.cpp @@ -85,12 +85,12 @@ void CRxCoreStateless::create(const CRxSlCfg &cfg) { /* create per port manager */ for (int i = 0; i < m_max_ports; i++) { const TRexPortAttr *port_attr = get_stateless_obj()->get_platform_api()->getPortAttrObj(i); - m_rx_port_mngr[i].create(cfg.m_ports[i], + m_rx_port_mngr[i].create(port_attr, + cfg.m_ports[i], m_rfc2544, &m_err_cntrs, &m_cpu_dp_u, - cfg.m_num_crc_fix_bytes, - port_attr); + cfg.m_num_crc_fix_bytes); } } @@ -189,6 +189,7 @@ void CRxCoreStateless::handle_work_stage() { /* set the next sync time to */ dsec_t sync_time_sec = now_sec() + (1.0 / 1000); + dsec_t tick_time_sec = now_sec() + 1.0; while (m_state == STATE_WORKING) { process_all_pending_pkts(); @@ -197,8 +198,11 @@ void CRxCoreStateless::handle_work_stage() { if ( (now - sync_time_sec) > 0 ) { periodic_check_for_cp_messages(); + } + + if ( (now - tick_time_sec) > 0) { port_manager_tick(); - sync_time_sec = now + (1.0 / 1000); + tick_time_sec = now + 1.0; } rte_pause(); @@ -211,6 +215,8 @@ void CRxCoreStateless::start() { m_monitor.create("STL RX CORE", 1); TrexWatchDog::getInstance().register_monitor(&m_monitor); + recalculate_next_state(); + while (m_state != STATE_QUIT) { switch (m_state) { case STATE_IDLE: @@ -334,7 +340,7 @@ CRxCoreStateless::disable_latency() { recalculate_next_state(); } -const RXPortManager & +RXPortManager & CRxCoreStateless::get_rx_port_mngr(uint8_t port_id) { assert(port_id < m_max_ports); return m_rx_port_mngr[port_id]; diff --git a/src/stateless/rx/trex_stateless_rx_core.h b/src/stateless/rx/trex_stateless_rx_core.h index cd16bb8a..96e511b4 100644 --- a/src/stateless/rx/trex_stateless_rx_core.h +++ b/src/stateless/rx/trex_stateless_rx_core.h @@ -151,7 +151,7 @@ class CRxCoreStateless { void enable_latency(); void disable_latency(); - const RXPortManager &get_rx_port_mngr(uint8_t port_id); + RXPortManager &get_rx_port_mngr(uint8_t port_id); private: void handle_cp_msg(TrexStatelessCpToRxMsgBase *msg); diff --git a/src/stateless/rx/trex_stateless_rx_port_mngr.cpp b/src/stateless/rx/trex_stateless_rx_port_mngr.cpp index af312700..e36f825d 100644 --- a/src/stateless/rx/trex_stateless_rx_port_mngr.cpp +++ b/src/stateless/rx/trex_stateless_rx_port_mngr.cpp @@ -23,6 +23,7 @@ #include "common/captureFile.h" #include "trex_stateless_rx_core.h" #include "common/Network/Packet/Arp.h" +#include "pkt_gen.h" /************************************** * latency RX feature @@ -507,16 +508,16 @@ protected: }; RXServer::RXServer() { - m_port_attr = NULL; m_io = NULL; + m_src_addr = NULL; m_port_id = 255; } void -RXServer::create(const TRexPortAttr *port_attr, CPortLatencyHWBase *io) { - m_port_attr = port_attr; - m_io = io; - m_port_id = port_attr->get_port_id(); +RXServer::create(uint8_t port_id, CPortLatencyHWBase *io, const CManyIPInfo *src_addr) { + m_port_id = port_id; + m_io = io; + m_src_addr = src_addr; } @@ -538,7 +539,7 @@ void RXServer::handle_icmp(RXPktParser &parser) { /* maybe not for us... */ - if (parser.m_ipv4->getDestIp() != m_port_attr->get_src_ipv4()) { + if (!m_src_addr->exists(parser.m_ipv4->getDestIp())) { return; } @@ -578,6 +579,7 @@ RXServer::handle_icmp(RXPktParser &parser) { void RXServer::handle_arp(RXPktParser &parser) { + MacAddress src_mac; /* only ethernet format supported */ if (parser.m_arp->getHrdType() != ArpHdr::ARP_HDR_HRD_ETHER) { @@ -595,7 +597,7 @@ RXServer::handle_arp(RXPktParser &parser) { } /* are we the target ? if not - go home */ - if (parser.m_arp->getTip() != m_port_attr->get_src_ipv4()) { + if (!m_src_addr->lookup(parser.m_arp->getTip(), 0, src_mac)) { return; } @@ -612,14 +614,14 @@ RXServer::handle_arp(RXPktParser &parser) { response_parser.m_arp->setOp(ArpHdr::ARP_HDR_OP_REPLY); /* fix the MAC addresses */ - response_parser.m_ether->mySource = m_port_attr->get_src_mac(); + response_parser.m_ether->mySource = src_mac; response_parser.m_ether->myDestination = parser.m_ether->mySource; /* fill up the fields */ /* src */ - response_parser.m_arp->m_arp_sha = m_port_attr->get_src_mac(); - response_parser.m_arp->setSip(m_port_attr->get_src_ipv4()); + response_parser.m_arp->m_arp_sha = src_mac; + response_parser.m_arp->setSip(parser.m_arp->getTip()); /* dst */ response_parser.m_arp->m_arp_tha = parser.m_arp->m_arp_sha; @@ -655,6 +657,44 @@ RXServer::duplicate_mbuf(const rte_mbuf_t *m) { } /************************************** + * Gratidious ARP + * + *************************************/ +void +RXGratARP::create(uint8_t port_id, CPortLatencyHWBase *io, CManyIPInfo *src_addr) { + m_io = io; + m_port_id = port_id; + m_src_addr = src_addr; +} + +void +RXGratARP::send_next_grat_arp() { + uint8_t src_mac[ETHER_ADDR_LEN]; + + const COneIPInfo *ip_info = m_src_addr->get_next_loop(); + if (!ip_info) { + return; + } + + rte_mbuf_t *m = CGlobalInfo::pktmbuf_alloc_small(CGlobalInfo::m_socket.port_to_socket(m_port_id)); + assert(m); + + uint8_t *p = (uint8_t *)rte_pktmbuf_append(m, ip_info->get_grat_arp_len()); + ip_info->get_mac(src_mac); + uint16_t vlan = ip_info->get_vlan(); + + /* for now only IPv4 */ + assert(ip_info->ip_ver() == COneIPInfo::IP4_VER); + uint32_t sip = ((COneIPv4Info *)ip_info)->get_ip(); + + CTestPktGen::create_arp_req(p, sip, sip, src_mac, vlan, m_port_id); + + m_io->tx(m); + + +} + +/************************************** * Port manager * *************************************/ @@ -663,26 +703,37 @@ RXPortManager::RXPortManager() { clear_all_features(); m_io = NULL; m_cpu_dp_u = NULL; + m_port_id = UINT8_MAX; } void -RXPortManager::create(CPortLatencyHWBase *io, +RXPortManager::create(const TRexPortAttr *port_attr, + CPortLatencyHWBase *io, CRFC2544Info *rfc2544, CRxCoreErrCntrs *err_cntrs, CCpuUtlDp *cpu_util, - uint8_t crc_bytes_num, - const TRexPortAttr *port_attr) { + uint8_t crc_bytes_num) { + + m_port_id = port_attr->get_port_id(); m_io = io; m_cpu_dp_u = cpu_util; m_num_crc_fix_bytes = crc_bytes_num; + /* if IPv4 is configured - add it to the grat service */ + uint32_t src_ipv4 = port_attr->get_src_ipv4(); + if (src_ipv4) { + m_src_addr.insert(COneIPv4Info(src_ipv4, 0, port_attr->get_src_mac(), m_port_id)); + } + /* init features */ m_latency.create(rfc2544, err_cntrs); - m_server.create(port_attr, io); + m_server.create(m_port_id, io, &m_src_addr); + m_grat_arp.create(m_port_id, io, &m_src_addr); /* by default, server feature is always on */ set_feature(SERVER); + set_feature(GRAT_ARP); } void RXPortManager::handle_pkt(const rte_mbuf_t *m) { @@ -706,7 +757,6 @@ void RXPortManager::handle_pkt(const rte_mbuf_t *m) { } } - int RXPortManager::process_all_pending_pkts(bool flush_rx) { rte_mbuf_t *rx_pkts[64]; @@ -747,8 +797,13 @@ RXPortManager::tick() { if (is_feature_set(RECORDER)) { m_recorder.flush_to_disk(); } + + if (is_feature_set(GRAT_ARP)) { + m_grat_arp.send_next_grat_arp(); + } } + Json::Value RXPortManager::to_json() const { Json::Value output = Json::objectValue; @@ -777,3 +832,4 @@ RXPortManager::to_json() const { return output; } + diff --git a/src/stateless/rx/trex_stateless_rx_port_mngr.h b/src/stateless/rx/trex_stateless_rx_port_mngr.h index 12b601ea..e72b0ff0 100644 --- a/src/stateless/rx/trex_stateless_rx_port_mngr.h +++ b/src/stateless/rx/trex_stateless_rx_port_mngr.h @@ -264,7 +264,7 @@ class RXServer { public: RXServer(); - void create(const TRexPortAttr *port_attr, CPortLatencyHWBase *io); + void create(uint8_t port_id, CPortLatencyHWBase *io, const CManyIPInfo *src_addr); void handle_pkt(const rte_mbuf_t *m); private: @@ -272,9 +272,36 @@ private: void handle_arp(RXPktParser &parser); rte_mbuf_t *duplicate_mbuf(const rte_mbuf_t *m); - const TRexPortAttr *m_port_attr; CPortLatencyHWBase *m_io; uint8_t m_port_id; + const CManyIPInfo *m_src_addr; +}; + +/************************************** + * Gratidious ARP + * + *************************************/ +class RXGratARP { +public: + RXGratARP() { + m_io = NULL; + m_port_id = UINT8_MAX; + m_src_addr = NULL; + } + + void create(uint8_t port_id, CPortLatencyHWBase *io, CManyIPInfo *src_addr); + + + /** + * the main 'tick' of the service + * + */ + void send_next_grat_arp(); + +private: + CPortLatencyHWBase *m_io; + CManyIPInfo *m_src_addr; + uint8_t m_port_id; }; /************************ manager ***************************/ @@ -291,22 +318,25 @@ public: LATENCY = 0x1, RECORDER = 0x2, QUEUE = 0x4, - SERVER = 0x8 + SERVER = 0x8, + GRAT_ARP = 0x10, }; RXPortManager(); - void create(CPortLatencyHWBase *io, + void create(const TRexPortAttr *port_attr, + CPortLatencyHWBase *io, CRFC2544Info *rfc2544, CRxCoreErrCntrs *err_cntrs, CCpuUtlDp *cpu_util, - uint8_t crc_bytes_num, - const TRexPortAttr *port_attr); + uint8_t crc_bytes_num); + void clear_stats() { m_latency.reset_stats(); } + void get_latency_stats(rx_per_flow_t *rx_stats, int min, int max, @@ -390,6 +420,15 @@ public: */ void tick(); + /** + * updates the source addresses registered with the port + * + */ + void update_src_addr(const CManyIPInfo &new_src_addr) { + /* deep copy */ + m_src_addr = new_src_addr; + } + bool has_features_set() { return (m_features != NO_FEATURES); } @@ -423,17 +462,19 @@ private: } uint32_t m_features; - + uint8_t m_port_id; RXLatency m_latency; RXPacketRecorder m_recorder; RXQueue m_queue; RXServer m_server; + RXGratARP m_grat_arp; // compensate for the fact that hardware send us packets without Ethernet CRC, and we report with it uint8_t m_num_crc_fix_bytes; CCpuUtlDp *m_cpu_dp_u; CPortLatencyHWBase *m_io; + CManyIPInfo m_src_addr; }; diff --git a/src/trex_port_attr.cpp b/src/trex_port_attr.cpp index 0ecbc2c4..2a68fcb9 100644 --- a/src/trex_port_attr.cpp +++ b/src/trex_port_attr.cpp @@ -99,7 +99,14 @@ TRexPortAttr::get_src_mac() const { return CGlobalInfo::m_options.get_src_mac_addr(m_port_id); } - +void +TRexPortAttr::set_src_ipv4(uint32_t addr) { + m_src_ipv4 = addr; + + /* when IP source changes - consider this as link down */ + m_dest.on_link_down(); +} + std::string TRexPortAttr::get_rx_filter_mode() const { switch (m_rx_filter_mode) { diff --git a/src/trex_port_attr.h b/src/trex_port_attr.h index c69314fc..437fa8c7 100755 --- a/src/trex_port_attr.h +++ b/src/trex_port_attr.h @@ -151,11 +151,7 @@ public: virtual int set_led(bool on) = 0; virtual int set_rx_filter_mode(rx_filter_mode_e mode) = 0; - void set_src_ipv4(uint32_t addr) { - m_src_ipv4 = addr; - /* when IP source changes - consider this as link down */ - m_dest.on_link_down(); - } + void set_src_ipv4(uint32_t addr); /* DUMPS */ virtual void dump_link(FILE *fd) = 0; diff --git a/src/utl_ip.cpp b/src/utl_ip.cpp index e7bb6fab..d29ab60a 100644 --- a/src/utl_ip.cpp +++ b/src/utl_ip.cpp @@ -71,13 +71,14 @@ void COneIPv6Info::fill_grat_arp_buf(uint8_t *p) { } const COneIPInfo *CManyIPInfo::get_next() { - COneIPInfo *ret; - + const COneIPInfo *ret; + if (!m_iter_initiated) { m_ipv4_iter = m_ipv4_resolve.begin(); m_iter_initiated = true; } + if (m_ipv4_iter == m_ipv4_resolve.end()) { m_ipv4_iter = m_ipv4_resolve.begin(); return NULL; @@ -99,13 +100,13 @@ void CManyIPInfo::dump(FILE *fd) { } } -void CManyIPInfo::insert(COneIPv4Info &ip_info) { +void CManyIPInfo::insert(const COneIPv4Info &ip_info) { CIpVlan ip_vlan(ip_info.get_ip(), ip_info.get_vlan()); m_ipv4_resolve.insert(std::make_pair(ip_vlan, ip_info)); } -bool CManyIPInfo::lookup(uint32_t ip, uint16_t vlan, MacAddress &ret_mac) { +bool CManyIPInfo::lookup(uint32_t ip, uint16_t vlan, MacAddress &ret_mac) const { ip_vlan_to_many_ip_iter_t it = m_ipv4_resolve.find(CIpVlan(ip, vlan)); if (it != m_ipv4_resolve.end()) { uint8_t mac[ETHER_ADDR_LEN]; @@ -117,6 +118,17 @@ bool CManyIPInfo::lookup(uint32_t ip, uint16_t vlan, MacAddress &ret_mac) { } } +bool CManyIPInfo::exists(uint32_t ip, uint16_t vlan) const { + ip_vlan_to_many_ip_iter_t it = m_ipv4_resolve.find(CIpVlan(ip, vlan)); + return (it != m_ipv4_resolve.end()); +} + +void CManyIPInfo::clear() { + m_ipv4_resolve.clear(); + m_ipv6_resolve.clear(); + m_iter_initiated = false; +} + const COneIPInfo *CManyIPInfo::get_first() { if (m_ipv4_resolve.size() == 0) { return NULL; diff --git a/src/utl_ip.h b/src/utl_ip.h index 27bb6c81..bab92c0f 100644 --- a/src/utl_ip.h +++ b/src/utl_ip.h @@ -156,7 +156,7 @@ class COneIPv4Info : public COneIPInfo { m_ip = ip; } ~COneIPv4Info() {}; - uint32_t get_ip() {return m_ip;} + uint32_t get_ip() const {return m_ip;} virtual uint8_t ip_ver() const {return IP4_VER;} virtual uint32_t get_arp_req_len() const {return 60;} virtual uint32_t get_grat_arp_len() const {return 60;} @@ -225,7 +225,7 @@ inline bool operator== (const COneIPv6Info& lhs, const COneIPv6Info& rhs) { inline bool operator!= (const COneIPv6Info& lhs, const COneIPv6Info& rhs){ return !(lhs == rhs); } typedef std::map<CIpVlan, COneIPv4Info> ip_vlan_to_many_ip_t; -typedef std::map<CIpVlan, COneIPv4Info>::iterator ip_vlan_to_many_ip_iter_t; +typedef std::map<CIpVlan, COneIPv4Info>::const_iterator ip_vlan_to_many_ip_iter_t; typedef std::map<std::pair<uint16_t[8], uint16_t>, COneIPv6Info> ipv6_vlan_to_many_ipv6_t; class CManyIPInfo { @@ -233,18 +233,37 @@ class CManyIPInfo { CManyIPInfo () { m_iter_initiated = false; } - void insert(COneIPv4Info &ip_info); - bool lookup(uint32_t ip, uint16_t vlan, MacAddress &ret_mac); + void insert(const COneIPv4Info &ip_info); + bool lookup(uint32_t ip, uint16_t vlan, MacAddress &ret_mac) const; + bool exists(uint32_t ip, uint16_t vlan = 0) const; + void clear(); + void dump(FILE *fd); uint32_t size() { return m_ipv4_resolve.size() + m_ipv6_resolve.size();} const COneIPInfo *get_first(); const COneIPInfo *get_next(); + const COneIPInfo *get_next_loop() { + const COneIPInfo *ip_info = get_next(); + return (ip_info ? ip_info : get_next()); + } + + CManyIPInfo& operator = (const CManyIPInfo &rhs) { + m_ipv4_resolve = rhs.m_ipv4_resolve; + m_ipv6_resolve = rhs.m_ipv6_resolve; + + m_iter_initiated = false; + return (*this); + } + private: - ip_vlan_to_many_ip_t m_ipv4_resolve; + ip_vlan_to_many_ip_t m_ipv4_resolve; + ipv6_vlan_to_many_ipv6_t m_ipv6_resolve; + ip_vlan_to_many_ip_iter_t m_ipv4_iter; - ipv6_vlan_to_many_ipv6_t m_ipv6_resolve; + bool m_iter_initiated; }; + #endif |