@@ -87,33 +87,61 @@ void IntfsOrch::doTask(Consumer &consumer)
87
87
}
88
88
89
89
auto it_intfs = m_syncdIntfses.find (alias);
90
- if (it_intfs == m_syncdIntfses.end () ||
91
- !m_syncdIntfses[alias].ip_addresses .contains (ip_prefix.getIp ()))
90
+ if (it_intfs == m_syncdIntfses.end ())
92
91
{
93
- if (it_intfs == m_syncdIntfses. end ( ))
92
+ if (addRouterIntfs (port ))
94
93
{
95
- if (addRouterIntfs (port))
96
- {
97
- IntfsEntry intfs_entry;
98
- intfs_entry.ref_count = 0 ;
99
- m_syncdIntfses[alias] = intfs_entry;
100
- }
101
- else
102
- {
103
- it++;
104
- continue ;
105
- }
94
+ IntfsEntry intfs_entry;
95
+ intfs_entry.ref_count = 0 ;
96
+ m_syncdIntfses[alias] = intfs_entry;
97
+ }
98
+ else
99
+ {
100
+ it++;
101
+ continue ;
106
102
}
107
-
108
- addSubnetRoute (port, ip_prefix);
109
- addIp2MeRoute (ip_prefix);
110
-
111
- m_syncdIntfses[alias].ip_addresses .add (ip_prefix.getIp ());
112
- it = consumer.m_toSync .erase (it);
113
103
}
114
- else
104
+
105
+ if (m_syncdIntfses[alias].ip_addresses .count (ip_prefix))
106
+ {
115
107
/* Duplicate entry */
116
108
it = consumer.m_toSync .erase (it);
109
+ continue ;
110
+ }
111
+
112
+ /* NOTE: Overlap checking is required to handle ifconfig weird behavior.
113
+ * When set IP address using ifconfig command it applies it in two stages.
114
+ * On stage one it sets IP address with netmask /8. On stage two it
115
+ * changes netmask to specified in command. As DB is async event to
116
+ * add IP address with original netmask may come before event to
117
+ * delete IP with netmask /8. To handle this we in case of overlap
118
+ * we should wait until entry with /8 netmask will be removed.
119
+ * Time frame between those event is quite small.*/
120
+ bool overlaps = false ;
121
+ for (const auto &prefixIt: m_syncdIntfses[alias].ip_addresses )
122
+ {
123
+ if (prefixIt.isAddressInSubnet (ip_prefix.getIp ()) ||
124
+ ip_prefix.isAddressInSubnet (prefixIt.getIp ()))
125
+ {
126
+ overlaps = true ;
127
+ SWSS_LOG_NOTICE (" Router interface %s IP %s overlaps with %s." , port.m_alias .c_str (),
128
+ prefixIt.to_string ().c_str (), ip_prefix.to_string ().c_str ());
129
+ break ;
130
+ }
131
+ }
132
+
133
+ if (overlaps)
134
+ {
135
+ /* Overlap of IP address network */
136
+ ++it;
137
+ continue ;
138
+ }
139
+
140
+ addSubnetRoute (port, ip_prefix);
141
+ addIp2MeRoute (ip_prefix);
142
+
143
+ m_syncdIntfses[alias].ip_addresses .insert (ip_prefix);
144
+ it = consumer.m_toSync .erase (it);
117
145
}
118
146
else if (op == DEL_COMMAND)
119
147
{
@@ -134,16 +162,16 @@ void IntfsOrch::doTask(Consumer &consumer)
134
162
135
163
if (m_syncdIntfses.find (alias) != m_syncdIntfses.end ())
136
164
{
137
- if (m_syncdIntfses[alias].ip_addresses .contains (ip_prefix. getIp () ))
165
+ if (m_syncdIntfses[alias].ip_addresses .count (ip_prefix))
138
166
{
139
167
removeSubnetRoute (port, ip_prefix);
140
168
removeIp2MeRoute (ip_prefix);
141
169
142
- m_syncdIntfses[alias].ip_addresses .remove (ip_prefix. getIp () );
170
+ m_syncdIntfses[alias].ip_addresses .erase (ip_prefix);
143
171
}
144
172
145
173
/* Remove router interface that no IP addresses are associated with */
146
- if (m_syncdIntfses[alias].ip_addresses .getSize () == 0 )
174
+ if (m_syncdIntfses[alias].ip_addresses .size () == 0 )
147
175
{
148
176
if (removeRouterIntfs (port))
149
177
{
0 commit comments