int if_menu(struct MAC *m){ struct datalink *pdl; int nif,i,j; char buf[100]; if( (pdl = get_if_list(&nif) ) == NULL){ fprintf(stderr,"Error getting interface list\n"); return -1; } for(i=0;i<nif;i++){ printf("%d: %s\n",i+1,pdl[i].dl_name); } j = i; do{ printf("Please choose interface (1-%d):\n",j); fgets(buf,sizeof(buf),stdin); sscanf(buf,"%d",&i); }while(i<1 || i>nif); if(openDatalink(pdl[i-1].dl_name) == -1){ fprintf(stderr,"Error opening interface %s\n",pdl[i-1].dl_name); return -1; } if(m != NULL) memcpy(m,pdl[i-1].dl_mac,6); return 0; }
void restore_rp_filter(void) { list ifs; element e; interface_t *ifp; unsigned rp_filter; #ifdef _HAVE_IPV4_DEVCONF_ sysctl_opts_t rpfilter_sysctl[] = { { IPV4_DEVCONF_RP_FILTER, 1 }, { 0, 0} }; #endif /* Restore the original settings of rp_filter, but only if they * are the same as what we set them to */ if (all_rp_filter == UINT_MAX) return; rp_filter = get_sysctl("net/ipv4/conf", "all", "rp_filter"); if (rp_filter == 0) { log_message(LOG_INFO, "NOTICE: resetting sysctl net.ipv4.conf.all.rp_filter to %d", all_rp_filter); set_sysctl("net/ipv4/conf", "all", "rp_filter", all_rp_filter); } if (default_rp_filter != UINT_MAX) { rp_filter = get_sysctl("net/ipv4/conf", "default", "rp_filter"); if (rp_filter == all_rp_filter) { log_message(LOG_INFO, "NOTICE: resetting sysctl net.ipv4.conf.default.rp_filter to %d", default_rp_filter); set_sysctl("net/ipv4/conf", "default", "rp_filter", default_rp_filter); } default_rp_filter = UINT_MAX; } ifs = get_if_list(); LIST_FOREACH(ifs, ifp, e) { if (ifp->rp_filter != UINT_MAX) { rp_filter = get_sysctl("net/ipv4/conf", ifp->ifname, "rp_filter"); if (rp_filter == all_rp_filter) { #ifdef _HAVE_IPV4_DEVCONF_ rpfilter_sysctl[0].value = ifp->rp_filter; netlink_set_interface_flags(ifp->ifindex, rpfilter_sysctl); #else set_sysctl("net/ipv4/conf", ifp->ifname, "rp_filter", ifp->rp_filter); #endif } } } all_rp_filter = UINT_MAX; }
/* Daemon init sequence */ static void start_vrrp(void) { /* Initialize sub-system */ init_interface_queue(); kernel_netlink_init(); gratuitous_arp_init(); ndisc_init(); global_data = alloc_global_data(); #ifdef _HAVE_LIBIPTC_ iptables_init(); #endif /* Parse configuration file */ vrrp_data = alloc_vrrp_data(); init_data(conf_file, vrrp_init_keywords); if (!vrrp_data) { stop_vrrp(); return; } init_global_data(global_data); /* Set the process priority and non swappable if configured */ if (global_data->vrrp_process_priority) set_process_priority(global_data->vrrp_process_priority); if (global_data->vrrp_no_swap) set_process_dont_swap(4096); /* guess a stack size to reserve */ #ifdef _WITH_SNMP_ if (!reload && (global_data->enable_snmp_keepalived || global_data->enable_snmp_rfcv2 || global_data->enable_snmp_rfcv3)) { vrrp_snmp_agent_init(global_data->snmp_socket); #ifdef _WITH_SNMP_RFC_ vrrp_start_time = timer_now(); #endif } #endif #ifdef _WITH_LVS_ if (vrrp_ipvs_needed()) { /* Initialize ipvs related */ if (ipvs_start() != IPVS_SUCCESS) { stop_vrrp(); return; } #ifdef _HAVE_IPVS_SYNCD_ /* If we are managing the sync daemon, then stop any * instances of it that may have been running if * we terminated abnormally */ ipvs_syncd_cmd(IPVS_STOPDAEMON, NULL, IPVS_MASTER, 0, true); ipvs_syncd_cmd(IPVS_STOPDAEMON, NULL, IPVS_BACKUP, 0, true); #endif } #endif if (reload) { clear_diff_saddresses(); #ifdef _HAVE_FIB_ROUTING_ clear_diff_srules(); clear_diff_sroutes(); #endif clear_diff_vrrp(); clear_diff_script(); } else { /* Clear leftover static entries */ netlink_iplist(vrrp_data->static_addresses, IPADDRESS_DEL); #ifdef _HAVE_FIB_ROUTING_ netlink_rtlist(vrrp_data->static_routes, IPROUTE_DEL); netlink_error_ignore = ENOENT; netlink_rulelist(vrrp_data->static_rules, IPRULE_DEL, true); netlink_error_ignore = 0; #endif } /* Complete VRRP initialization */ if (!vrrp_complete_init()) { if (vrrp_ipvs_needed()) { stop_vrrp(); } return; } #ifdef _HAVE_LIBIPTC_ iptables_startup(); #endif /* Post initializations */ #ifdef _DEBUG_ log_message(LOG_INFO, "Configuration is using : %lu Bytes", mem_allocated); #endif /* Set static entries */ netlink_iplist(vrrp_data->static_addresses, IPADDRESS_ADD); #ifdef _HAVE_FIB_ROUTING_ netlink_rtlist(vrrp_data->static_routes, IPROUTE_ADD); netlink_rulelist(vrrp_data->static_rules, IPRULE_ADD, false); #endif /* Dump configuration */ if (__test_bit(DUMP_CONF_BIT, &debug)) { list ifl; dump_global_data(global_data); dump_vrrp_data(vrrp_data); ifl = get_if_list(); if (!LIST_ISEMPTY(ifl)) dump_list(ifl); } /* Initialize linkbeat */ init_interface_linkbeat(); /* Init & start the VRRP packet dispatcher */ thread_add_event(master, vrrp_dispatcher_init, NULL, VRRP_DISPATCHER); }
/* IPv4 VMAC interfaces require rp_filter to be 0; this in turn requires * net.ipv4.conf.all.rp_filter to be 0, but if it is non-zero, then all * interfaces will be operating with a non-zero value of rp_filter. * In this function, if all.rp_filter > 0 and default.rp_filter < all.rp_filter, * we first set default.rp_filter to the current value of all.rp_filter, * so that any new interfaces are created with the current value of all.rp_filter. * We then iterate through all interfaces, and if {interface}.rp_filter < all.rp_filter * we set {interface}.rp_filter = all.rp_filter. * Finally we set all.rp_filter = 0. * * This should not alter the operation of any interface, or any interface * subsequently created, but it does allow us to set rp_filter = 0 * on vmac interfaces. */ static void clear_rp_filter(void) { list ifs; element e; interface_t *ifp; unsigned rp_filter; #ifdef _HAVE_IPV4_DEVCONF_ sysctl_opts_t rpfilter_sysctl[] = { { IPV4_DEVCONF_RP_FILTER, 1 }, { 0, 0} }; #endif rp_filter = get_sysctl("net/ipv4/conf", "all", "rp_filter"); if (rp_filter == UINT_MAX) { log_message(LOG_INFO, "Unable to read sysctl net.ipv4.conf.all.rp_filter"); return; } if (rp_filter == 0) return; /* Save current value of all/rp_filter */ all_rp_filter = rp_filter; /* We want to ensure that default/rp_filter is at least the value of all/rp_filter */ rp_filter = get_sysctl("net/ipv4/conf", "default", "rp_filter"); if (rp_filter < all_rp_filter) { log_message(LOG_INFO, "NOTICE: setting sysctl net.ipv4.conf.default.rp_filter from %d to %d", rp_filter, all_rp_filter); set_sysctl("net/ipv4/conf", "default", "rp_filter", all_rp_filter); default_rp_filter = rp_filter; } /* Now ensure rp_filter for all interfaces is at least all/rp_filter. */ #ifdef _HAVE_IPV4_DEVCONF_ rpfilter_sysctl[0].value = all_rp_filter; #endif kernel_netlink_poll(); /* Update our view of interfaces first */ ifs = get_if_list(); LIST_FOREACH(ifs, ifp, e) { if (!ifp->ifindex) continue; #ifndef _HAVE_IPV4_DEVCONF_ if ((ifp->rp_filter = get_sysctl("net/ipv4/conf", ifp->ifname, "rp_filter")) == UINT_MAX) log_message(LOG_INFO, "Unable to read rp_filter for %s", ifp->ifname); else #endif if (ifp->rp_filter < all_rp_filter) { #ifdef _HAVE_IPV4_DEVCONF_ netlink_set_interface_flags(ifp->ifindex, rpfilter_sysctl); #else set_sysctl("net/ipv4/conf", ifp->ifname, "rp_filter", all_rp_filter); #endif } else { /* Indicate we are not setting it */ ifp->rp_filter = UINT_MAX; } } /* We have now made sure that all the interfaces have rp_filter >= all_rp_filter */ log_message(LOG_INFO, "NOTICE: setting sysctl net.ipv4.conf.all.rp_filter from %d to 0", all_rp_filter); set_sysctl("net/ipv4/conf", "all", "rp_filter", 0); }