📄 hello.c
字号:
if (BIT_TEST(tlp->target_ifap->ifa_ps[tp->task_rtproto].ips_state, IFPS_NOIN)) { register rt_entry *rt; register gw_entry *gwp; GW_LIST(hello_gw_list, gwp) { RTQ_LIST(&gwp->gw_rtq, rt) { if (RT_IFAP(rt) == tlp->target_ifap) { rt_delete(rt); changes++; } } RTQ_LIST_END(&gwp->gw_rtq, rt) ; } GW_LIST(hello_gw_list, gwp) ; } } switch (BIT_TEST(tlp->target_flags, TARGETF_POLICY|TARGETF_SUPPLY)) { case TARGETF_SUPPLY: /* Need to run policy for this target */ if (!have_list) { /* Get target list */ rthl = rthlist_active(AF_INET); have_list++; } if (rthl) { /* and run policy */ changes += hello_policy(tp, tlp, rthl); } /* Indicate policy has been run */ BIT_SET(tlp->target_flags, TARGETF_POLICY); break; case TARGETF_POLICY: /* Indicate policy run on this target */ BIT_RESET(tlp->target_flags, TARGETF_POLICY); break; default: break; } } TARGET_LIST_END(tlp, &hello_targets) ; if (rthl) { RTLIST_RESET(rthl); } rt_close(tp, (gw_entry *) 0, 0, NULL); if (changes && !BIT_TEST(hello_flags, HELLOF_RECONFIG)) { hello_need_flash(tp); } } if (targets != n_targets || hello_n_source != n_source) { tracef("hello_target_list: "); if (targets) { tracef("supplying updates to"); if (targets - hello_n_source) { tracef(" %d interface%s", targets - hello_n_source, (targets - hello_n_source) > 1 ? "s" : ""); } if (hello_n_source) { tracef(" %d gateways", hello_n_source); } } else { tracef("just listening"); } n_targets = targets; n_source = hello_n_source; trace_log_tp(tp, TRC_NL_AFTER, LOG_INFO, (NULL)); } hello_target_list_job = (task_job *) 0;}/* * Reinit after parse *//*ARGSUSED*/static voidhello_reinit __PF1(tp, task *){ int entries = 0; gw_entry *gwp; trace_inherit_global(hello_trace_options, hello_trace_types, (flag_t) 0); trace_set(tp->task_trace, hello_trace_options); /* Open the routing table */ rt_open(tp); GW_LIST(hello_gw_list, gwp) { rt_entry *rt; RTQ_LIST(&gwp->gw_rtq, rt) { pref_t preference = hello_preference; /* Calculate preference of this route */ if (import(rt->rt_dest, rt->rt_dest_mask, hello_import_list, RT_IFAP(rt)->ifa_ps[tp->task_rtproto].ips_import, rt->rt_gwp->gw_import, &preference, RT_IFAP(rt), (void_t) 0)) { if (rt->rt_preference != preference) { /* The preference has changed, change the route */ (void) rt_change(rt, rt->rt_metric, rt->rt_metric2, rt->rt_tag, preference, rt->rt_preference2, rt->rt_n_gw, rt->rt_routers); } entries++; } else { /* This route is now restricted */ rt_delete(rt); } } RTQ_LIST_END(&gwp->gw_rtq, rt) ; } GW_LIST(hello_gw_list, gwp) ; /* Close the routing table */ rt_close(tp, (gw_entry *) 0, entries, NULL); /* Indicate a reconfig in process */ BIT_SET(hello_flags, HELLOF_RECONFIG);}/* * Deal with interface policy */static voidhello_control_reset __PF2(tp, task *, ifap, if_addr *){ struct ifa_ps *ips = &ifap->ifa_ps[tp->task_rtproto]; BIT_RESET(ips->ips_state, IFPS_RESET); ips->ips_metric_in = hop_to_hello[ifap->ifa_metric] + HELLO_HOP; ips->ips_metric_out = (metric_t) 0;}static voidhello_control_set __PF2(tp, task *, ifap, if_addr *){ struct ifa_ps *ips = &ifap->ifa_ps[tp->task_rtproto]; config_entry **list = config_resolv_ifa(hello_int_policy, ifap, HELLO_CONFIG_MAX); /* Reset */ hello_control_reset(tp, ifap); /* Set defaults */ switch (BIT_TEST(ifap->ifa_state, IFS_POINTOPOINT|IFS_LOOPBACK|IFS_BROADCAST)) { case IFS_LOOPBACK: /* By default we do not send or listen on the loopback */ /* interface. */ BIT_SET(ips->ips_state, IFPS_NOIN|IFPS_NOOUT); break; case IFS_POINTOPOINT: /* By default we do not send HELLO out a P2P interface. */ BIT_SET(ips->ips_state, IFPS_NOOUT); break; case IFS_BROADCAST: default: /* On broadcast and NBMA interfaces we default to sending and */ /* receiving. */ break; } /* Process configuration info */ if (list) { int type = HELLO_CONFIG_MAX; config_entry *cp; /* Fill in the parameters */ while (--type) { if ((cp = list[type])) { switch (type) { case HELLO_CONFIG_IN: if (cp->config_data) { BIT_RESET(ips->ips_state, IFPS_NOIN); } else { BIT_SET(ips->ips_state, IFPS_NOIN); } break; case HELLO_CONFIG_OUT: if (cp->config_data) { BIT_RESET(ips->ips_state, IFPS_NOOUT); } else { BIT_SET(ips->ips_state, IFPS_NOOUT); } break; case HELLO_CONFIG_METRICIN: BIT_SET(ips->ips_state, IFPS_METRICIN); ips->ips_metric_in = (metric_t) cp->config_data; break; case HELLO_CONFIG_METRICOUT: BIT_SET(ips->ips_state, IFPS_METRICOUT); ips->ips_metric_out = (metric_t) cp->config_data; break; } } } config_resolv_free(list, HELLO_CONFIG_MAX); }}/* * Terminating - clean up */static voidhello_terminate __PF1(tp, task *){ if_addr *ifap; /* Release the target list, bit assignments, and buffers */ target_free_list(tp, &hello_targets); /* Reset the policy */ IF_ADDR(ifap) { if (socktype(ifap->ifa_addr) == AF_INET) { hello_control_reset(tp, ifap); } } IF_ADDR_END(ifap) ; { gw_entry *gwp; rt_open(tp); GW_LIST(hello_gw_list, gwp) { rt_entry *rt = (rt_entry *) 0; RTQ_LIST(&gwp->gw_rtq, rt) { rt_delete(rt); } RTQ_LIST_END(&gwp->gw_rtq, rt) ; } GW_LIST(hello_gw_list, gwp) ; rt_close(tp, (gw_entry *) 0, 0, NULL); } hello_cleanup(tp); task_delete(tp); hello_timer_update = hello_timer_flash = hello_timer_age = (task_timer *) 0;}/* * Deal with an interface status change */static voidhello_ifachange __PF2(tp, task *, ifap, if_addr *){ int changes = 0; gw_entry *gwp; if (socktype(ifap->ifa_addr) != AF_INET) { return; } rt_open(tp); switch (ifap->ifa_change) { case IFC_NOCHANGE: case IFC_ADD: if (BIT_TEST(ifap->ifa_state, IFS_UP)) { hello_control_set(tp, ifap); } break; case IFC_DELETE: case IFC_DELETE|IFC_UPDOWN: Delete: GW_LIST(hello_gw_list, gwp) { rt_entry *rt = (rt_entry *) 0; RTQ_LIST(&gwp->gw_rtq, rt) { if (RT_IFAP(rt) == ifap) { rt_delete(rt); changes++; } } RTQ_LIST_END(&gwp->gw_rtq, rt) ; } GW_LIST(hello_gw_list, gwp) ; hello_control_reset(tp, ifap); break; default: /* Something has changed */ if (BIT_TEST(ifap->ifa_change, IFC_UPDOWN)) { if (BIT_TEST(ifap->ifa_state, IFS_UP)) { /* Down to Up transition */ hello_control_set(tp, ifap); } else { /* UP to DOWN transition */ goto Delete; } } if (BIT_TEST(ifap->ifa_change, IFC_NETMASK)) { /* The netmask has changed, delete any routes that */ /* point at gateways that are no longer reachable */ target *tlp; GW_LIST(hello_gw_list, gwp) { rt_entry *rt = (rt_entry *) 0; RTQ_LIST(&gwp->gw_rtq, rt) { if (RT_IFAP(rt) == ifap && (if_withdstaddr(RT_ROUTER(rt)) != ifap || BIT_TEST(rt->rt_state, RTS_IFSUBNETMASK))) { /* Interface for this route has changed or we derived the subnet mask */ rt_delete(rt); changes++; } } RTQ_LIST_END(&gwp->gw_rtq, rt) ; } GW_LIST(hello_gw_list, gwp) ; TARGET_LIST(tlp, &hello_targets) { if (tlp->target_ifap == ifap && BIT_TEST(tlp->target_flags, TARGETF_SUPPLY)) { /* Some subnet masks may have been derrived, indicate that policy needs to be rerun */ BIT_RESET(tlp->target_flags, TARGETF_POLICY); } } TARGET_LIST_END(tlp, &hello_targets) ; } if (BIT_TEST(ifap->ifa_change, IFC_METRIC)) { struct ifa_ps *ips = &ifap->ifa_ps[tp->task_rtproto]; if (!BIT_TEST(ips->ips_state, IFPS_METRICIN)) { ips->ips_metric_in = hop_to_hello[ifap->ifa_metric] + HELLO_HOP; } } /* A METRIC change will take effect in 15 seconds with the next update received */ /* A BROADCAST change is automatic since we have a pointer to the pointer to */ /* the broadcast address */ /* An ADDR change will take effect when the peers notice that the */ /* old address is no longer sending */ /* An MTU change will take effect when we get around to sending packets */ /* A SEL change is of no interest to us */ break; } rt_close(tp, (gw_entry *) 0, changes, NULL); /* Schedule a target list rebuild if necessary */ if (!hello_target_list_job) { hello_target_list_job = task_job_create(tp, TASK_JOB_FG, "Target_Build", hello_target_list, (void_t) 0); }}static voidhello_int_dump __PF2(fd, FILE *, list, config_entry *){ register config_entry *cp; CONFIG_LIST(cp, list) { switch (cp->config_type) { case HELLO_CONFIG_IN: (void) fprintf(fd, " %shelloin", cp->config_data ? "" : "no"); break; case HELLO_CONFIG_OUT: (void) fprintf(fd, " %shelloout", cp->config_data ? "" : "no"); break; case HELLO_CONFIG_METRICIN: (void) fprintf(fd, " metricin %u", (metric_t) cp->config_data); break; case HELLO_CONFIG_METRICOUT: (void) fprintf(fd, " metricout %u", (metric_t) cp->config_data); break; default: assert(FALSE); break; } } CONFIG_LIST_END(cp, list) ;}/* * Dump info about HELLO */static voidhello_dump __PF2(tp, task *, fd, FILE *){ (void) fprintf(fd, "\tFlags: %s\tDefault metric: %d\t\tDefault preference: %d\n", trace_bits(hello_flag_bits, hello_flags), hello_default_metric, hello_preference); target_dump(fd, &hello_targets, (bits *) 0); if (hello_gw_list) { (void) fprintf(fd, "\tActive gateways:\n"); gw_dump(fd, "\t\t", hello_gw_list, tp->task_rtproto); (void) fprintf(fd, "\n"); } if (hello_int_policy) { (void) fprintf(fd, "\tInterface policy:\n"); control_interface_dump(fd, 2, hello_int_policy, hello_int_dump); } control_import_dump(fd, 1, RTPROTO_HELLO, hello_import_list, hello_gw_list); control_export_dump(fd, 1, RTPROTO_HELLO, hello_export_list, hello_gw_list); (void) fprintf(fd, "\n");}/* * Initialize HELLO socket and task *//*ARGSUSED*/voidhello_init __PF0(void){ _PROTOTYPE(flash, void, (task *, rt_list *)) = hello_flash; /* Hack for UTX/32 and Ultrix */ _PROTOTYPE(newpolicy, void, (task *, rt_list *)) = hello_newpolicy; /* ditto */ static task *hello_task; if (!hello_win_block_index) { hello_win_block_index = task_block_init(sizeof (struct hello_win), "hello_win"); } if (BIT_TEST(hello_flags, HELLOF_ON)) { if (!hello_task) { trace_inherit_global(hello_trace_options, hello_trace_types, (flag_t) 0); hello_task = task_alloc("HELLO", TASKPRI_PROTO, hello_trace_options); hello_task->task_proto = IPPROTO_HELLO; hello_task->task_rtproto = RTPROTO_HELLO; task_set_recv(hello_task, hello_recv); task_set_cleanup(hello_task, hello_cleanup); task_set_reinit(hello_task, hello_reinit); task_set_dump(hello_task, hello_dump); task_set_terminate(hello_task, hello_terminate); task_set_ifachange(hello_task, hello_ifachange); task_set_flash(hello_task, flash); task_set_newpolicy(hello_task, newpolicy); if ((hello_task->task_socket = task_get_socket(hello_task, AF_INET, SOCK_RAW, IPPROTO_HELLO)) < 0) { task_quit(errno); } if (task_set_option(hello_task, TASKOPTION_RECVBUF, task_maxpacket) < 0) { task_quit(errno); } if (task_set_option(hello_task, TASKOPTION_DONTROUTE, TRUE) < 0) { task_quit(errno); } if (task_set_option(hello_task, TASKOPTION_NONBLOCKING, (caddr_t) TRUE) < 0) { task_quit(errno); } (void) task_set_option(hello_task, TASKOPTION_TTL, 1); if (!task_create(hello_task)) { task_quit(EINVAL); } } } else { hello_cleanup((task *) 0); if (hello_task) { hello_terminate(hello_task); hello_task = (task *) 0; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -