@@ -263,6 +263,40 @@ static int manager_connect_genl(Manager *m) {
263263 return 0 ;
264264}
265265
266+ static int manager_setup_rtnl_filter (Manager * manager ) {
267+ struct sock_filter filter [] = {
268+ /* Check the packet length. */
269+ BPF_STMT (BPF_LD + BPF_W + BPF_LEN , 0 ), /* A <- packet length */
270+ BPF_JUMP (BPF_JMP + BPF_JGE + BPF_K , sizeof (struct nlmsghdr ), 1 , 0 ), /* A (packet length) >= sizeof(struct nlmsghdr) ? */
271+ BPF_STMT (BPF_RET + BPF_K , 0 ), /* reject */
272+ /* Always accept multipart message. */
273+ BPF_STMT (BPF_LD + BPF_H + BPF_ABS , offsetof(struct nlmsghdr , nlmsg_flags )), /* A <- message flags */
274+ BPF_JUMP (BPF_JMP + BPF_JSET + BPF_K , htobe16 (NLM_F_MULTI ), 0 , 1 ), /* message flags has NLM_F_MULTI ? */
275+ BPF_STMT (BPF_RET + BPF_K , UINT32_MAX ), /* accept */
276+ /* Accept all message types except for RTM_NEWNEIGH or RTM_DELNEIGH. */
277+ BPF_STMT (BPF_LD + BPF_H + BPF_ABS , offsetof(struct nlmsghdr , nlmsg_type )), /* A <- message type */
278+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K , htobe16 (RTM_NEWNEIGH ), 2 , 0 ), /* message type == RTM_NEWNEIGH ? */
279+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K , htobe16 (RTM_DELNEIGH ), 1 , 0 ), /* message type == RTM_DELNEIGH ? */
280+ BPF_STMT (BPF_RET + BPF_K , UINT32_MAX ), /* accept */
281+ /* Check the packet length. */
282+ BPF_STMT (BPF_LD + BPF_W + BPF_LEN , 0 ), /* A <- packet length */
283+ BPF_JUMP (BPF_JMP + BPF_JGE + BPF_K , sizeof (struct nlmsghdr ) + sizeof (struct ndmsg ), 1 , 0 ),
284+ /* packet length >= sizeof(struct nlmsghdr) + sizeof(struct ndmsg) ? */
285+ BPF_STMT (BPF_RET + BPF_K , 0 ), /* reject */
286+ /* Reject the message when the neighbor state does not have NUD_PERMANENT flag. */
287+ BPF_STMT (BPF_LD + BPF_H + BPF_ABS , sizeof (struct nlmsghdr ) + offsetof(struct ndmsg , ndm_state )),
288+ /* A <- neighbor state */
289+ BPF_JUMP (BPF_JMP + BPF_JSET + BPF_K , htobe16 (NUD_PERMANENT ), 1 , 0 ), /* neighbor state has NUD_PERMANENT ? */
290+ BPF_STMT (BPF_RET + BPF_K , 0 ), /* reject */
291+ BPF_STMT (BPF_RET + BPF_K , UINT32_MAX ), /* accept */
292+ };
293+
294+ assert (manager );
295+ assert (manager -> rtnl );
296+
297+ return sd_netlink_attach_filter (manager -> rtnl , ELEMENTSOF (filter ), filter );
298+ }
299+
266300static int manager_connect_rtnl (Manager * m ) {
267301 int fd , r ;
268302
@@ -337,7 +371,7 @@ static int manager_connect_rtnl(Manager *m) {
337371 if (r < 0 )
338372 return r ;
339373
340- return 0 ;
374+ return manager_setup_rtnl_filter ( m ) ;
341375}
342376
343377static int manager_dirty_handler (sd_event_source * s , void * userdata ) {
0 commit comments