/** * Updates the Kernel routing table. If activate is 1, the route * is (re-)activated. If activate is false, the route is removed. */ int internUpdateKernelRoute(struct RouteTable *route, int activate) { struct MRouteDesc mrDesc; struct IfDesc *Dp; unsigned Ix; struct IfDesc* upstrIf; // Get the upstream VIF... upstrIf = getIfByIx( upStreamVif ); if(upstrIf == NULL) atlog(LOG_ERR, 0 ,"FATAL: Unable to get Upstream IF."); if( IN6_ARE_ADDR_EQUAL( &(route->group), &allzero_addr ) ) return 1; if( IN6_ARE_ADDR_EQUAL( &(route->originAddr), &allzero_addr ) ) return 1; // Build route descriptor from table entry... // Set the source address and group address... mrDesc.McAdr.sin6_addr = route->group; mrDesc.McAdr.sin6_family = AF_INET6; mrDesc.McAdr.sin6_flowinfo = 0; mrDesc.McAdr.sin6_port = 0; mrDesc.McAdr.sin6_scope_id = upstrIf->index; mrDesc.OriginAdr.sin6_addr = route->originAddr; // clear output interfaces memset( mrDesc.TtlVc, 0, sizeof( mrDesc.TtlVc ) ); IF_DEBUG atlog(LOG_DEBUG, 0, "Vif bits : 0x%08x", route->vifBits); for( Ix = 0 ; Ix < MAXMIFS; Ix++ ) { Dp = getIfDescFromMifByIx(Ix); if (Dp == NULL) break; if ( Dp->state == IF_STATE_UPSTREAM ) mrDesc.InVif = Ix; else if(BIT_TST(route->vifBits, Dp->index)) { mrDesc.TtlVc[ Ix ] = Dp->threshold; } } // Do the actual Kernel route update... if(activate) { // Add route in kernel... addMRoute( &mrDesc ); } else { // Delete the route from Kernel... delMRoute( &mrDesc ); } return 1; }
bool_e bitfield_get(bitfield_t *b, uint32_t *bit) { *bit = 0xFFFFFFFF; if (b && b->fields) { uint32_t c = 0; // calculated bit uint32_t d = 0; // intrafield bit uint32_t i = 0; // index uint32_t l = bitfield_length(b) / 4; for (i = 0; i < l; i++) { for (d = 0; d < 32; d++) { // the calculated bit c = d + (i * 32); // if the bit is higher than is allowed, fail if (c >= b->max) return false_e; if (!BIT_TST(b->fields[i], d)) { BIT_SET(b->fields[i], d); *bit = c; return true_e; } } } } return false_e; }
/* Send a Route Reply to the reservation protocol. The Route Query * contains the query to which we are responding. The flags contain * the incoming flags from the query or, for route change * notification, the flags that should be set for the reply. The * kernel table entry contains the routing info to use for a route * change notification. */ static int rsrr_accept_rq(struct rsrr_rq *route_query, int flags, struct gtable *gt_notify) { struct rsrr_header *rsrr; struct rsrr_rr *route_reply; struct gtable *gt,local_g; struct rtentry *r; int sendlen; u_long mcastgrp; /* Set up message */ rsrr = (struct rsrr_header *) rsrr_send_buf; rsrr->version = 1; rsrr->type = RSRR_ROUTE_REPLY; rsrr->flags = 0; rsrr->num = 0; route_reply = (struct rsrr_rr *) (rsrr_send_buf + RSRR_HEADER_LEN); route_reply->dest_addr.s_addr = route_query->dest_addr.s_addr; route_reply->source_addr.s_addr = route_query->source_addr.s_addr; route_reply->query_id = route_query->query_id; /* Blank routing entry for error. */ route_reply->in_vif = 0; route_reply->reserved = 0; route_reply->out_vif_bm = 0; /* Get the size. */ sendlen = RSRR_RR_LEN; /* If kernel table entry is defined, then we are sending a Route Reply * due to a Route Change Notification event. Use the kernel table entry * to supply the routing info. */ if (gt_notify) { /* Set flags */ rsrr->flags = flags; /* Include the routing entry. */ route_reply->in_vif = gt_notify->gt_route->rt_parent; if (BIT_TST(flags,RSRR_NOTIFICATION_BIT)) route_reply->out_vif_bm = gt_notify->gt_grpmems; else route_reply->out_vif_bm = 0; } else if (find_src_grp(route_query->source_addr.s_addr, 0, route_query->dest_addr.s_addr)) { /* Found kernel entry. Code taken from add_table_entry() */ gt = gtp ? gtp->gt_gnext : kernel_table; /* Include the routing entry. */ route_reply->in_vif = gt->gt_route->rt_parent; route_reply->out_vif_bm = gt->gt_grpmems; /* Cache reply if using route change notification. */ if BIT_TST(flags,RSRR_NOTIFICATION_BIT) { rsrr_cache(gt,route_query); BIT_SET(rsrr->flags,RSRR_NOTIFICATION_BIT); }
/** * Returns true when the given group belongs to the given interface */ int interfaceInRoute(int32_t group, int Ix) { struct RouteTable* croute; croute = findRoute(group); if (croute != NULL) { my_log(LOG_DEBUG, 0, "Interface id %d is in group $d", Ix, group); return BIT_TST(croute->vifBits, Ix); } else { return 0; } }
/** * Counts the number of interfaces a given route is active on */ int numberOfInterfaces(struct RouteTable *croute) { int Ix; struct IfDesc *Dp; int result = 0; // Loop through all interfaces for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) { // If the interface is used by the route, increase counter if(BIT_TST(croute->vifBits, Dp->index)) { result++; } } my_log(LOG_DEBUG, 0, "counted %d interfaces", result); return result; }
/** * Updates the Kernel routing table. If activate is 1, the route * is (re-)activated. If activate is false, the route is removed. */ int internUpdateKernelRoute(struct RouteTable *route, int activate) { struct MRouteDesc mrDesc; struct IfDesc *Dp; unsigned Ix; int i; for (int i = 0; i < MAX_ORIGINS; i++) { if (route->originAddrs[i] == 0 || route->upstrVif == -1) { continue; } // Build route descriptor from table entry... // Set the source address and group address... mrDesc.McAdr.s_addr = route->group; mrDesc.OriginAdr.s_addr = route->originAddrs[i]; // clear output interfaces memset( mrDesc.TtlVc, 0, sizeof( mrDesc.TtlVc ) ); my_log(LOG_DEBUG, 0, "Vif bits : 0x%08x", route->vifBits); mrDesc.InVif = route->upstrVif; // Set the TTL's for the route descriptor... for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) { if(Dp->state == IF_STATE_UPSTREAM) { continue; } else if(BIT_TST(route->vifBits, Dp->index)) { my_log(LOG_DEBUG, 0, "Setting TTL for Vif %d to %d", Dp->index, Dp->threshold); mrDesc.TtlVc[ Dp->index ] = Dp->threshold; } } // Do the actual Kernel route update... if(activate) { // Add route in kernel... addMRoute( &mrDesc ); } else { // Delete the route from Kernel... delMRoute( &mrDesc ); } } return 1; }
bool_e bitfield_rls(bitfield_t *b, uint32_t bit) { if (b && b->fields) { uint32_t c = 0; // calculated bit uint32_t d = 0; // intrafield bit uint32_t i = 0; // index uint32_t l = bitfield_length(b) / 4; for (i = 0; i < l; i++) { for (d = 0; d < 32; d++) { c = d + (i * 32); if (c == bit && BIT_TST(b->fields[i], d)) { BIT_CLR(b->fields[i], d); return true_e; } } } } return false_e; }
void ipmi_msg_proc_task(void *args) { uint8_t err; uint16_t new_sel_id; sel_event_record newsel; struct event_request_message *evm; struct ipmi_req *req; char msg_cmd[32] = {0}; while (1) { evm = (struct event_request_message *)OSQPend(ipmi_global.ipmi_msg_que, 0, &err); if (err) { ipmi_err(); continue; } newsel.record_type = 0x02; newsel.sel_type.standard_type.id_type = 0x1; newsel.sel_type.standard_type.ipmb_slave_addr = 0x0; newsel.sel_type.standard_type.ipmb_dev_lun = 0x0; newsel.sel_type.standard_type.channel_number = 0x0; newsel.sel_type.standard_type.evm_rev = evm->evm_rev; newsel.sel_type.standard_type.sensor_type = evm->sensor_type; newsel.sel_type.standard_type.sensor_num = evm->sensor_num; newsel.sel_type.standard_type.event_type = evm->event_type; newsel.sel_type.standard_type.event_dir = evm->event_dir; newsel.sel_type.standard_type.event_data[0] = evm->event_data[0]; newsel.sel_type.standard_type.event_data[1] = evm->event_data[1]; newsel.sel_type.standard_type.event_data[2] = evm->event_data[2]; // add sel to eeprom new_sel_id = ipmi_add_sel(&newsel, newsel.record_type); if (new_sel_id == 0) { ipmi_err(); } if (BIT_TST(ipmi_global.bmc_global_enable, EN_EVT_MSG_BUF_FUL_INT)) { BIT_SET(ipmi_global.bmc_message_flags, EN_EVT_MSG_BUF_FUL_INT); } // event receiver is enable, send the event message to IPMB #if 0 if (ipmi_global.event_recv_addr != 0xff) { req = (struct ipmi_req *)&msg_cmd[0]; req->msg.data_len = sizeof(struct _ipmi_req_cmd) + sizeof(struct event_request_message); req->msg.rs_sa = ipmi_global.event_recv_addr; req->msg.rs_lun = ipmi_global.event_recv_lun;; req->msg.netfn = PLATFORM_EVENT; req->msg.cmd = IPMI_NETFN_REQ_SE; req->msg.rq_sa = ipmi_global.ipmb_addr; req->msg.rq_lun = 0x0; req->msg.rq_seq = 0x01; req->msg.checksum1 = 0xff; memcpy(&req->data[0], evm, sizeof(struct event_request_message)); err = I2C_i2c0_ipmb_write(req->msg.rs_sa, msg_cmd, req->msg.data_len); DEBUG("send msg to receiver rq_sa=0x%x, rs_sa=0x%x err=0x%x\r\n", req->msg.rq_sa, req->msg.rs_sa, err); } #endif } }
/* Accept a message from the reservation protocol and take * appropriate action. */ static void rsrr_accept(int recvlen) { struct rsrr_header *rsrr; struct rsrr_rq *route_query; if (recvlen < RSRR_HEADER_LEN) { logit(LOG_WARNING, 0, "Received RSRR packet of %d bytes, which is less than min size", recvlen); return; } rsrr = (struct rsrr_header *) rsrr_recv_buf; if (rsrr->version > RSRR_MAX_VERSION) { logit(LOG_WARNING, 0, "Received RSRR packet version %d, which I don't understand", rsrr->version); return; } switch (rsrr->version) { case 1: switch (rsrr->type) { case RSRR_INITIAL_QUERY: /* Send Initial Reply to client */ logit(LOG_INFO, 0, "Received Initial Query\n"); rsrr_accept_iq(); break; case RSRR_ROUTE_QUERY: /* Check size */ if (recvlen < RSRR_RQ_LEN) { logit(LOG_WARNING, 0, "Received Route Query of %d bytes, which is too small", recvlen); break; } /* Get the query */ route_query = (struct rsrr_rq *) (rsrr_recv_buf + RSRR_HEADER_LEN); logit(LOG_INFO, 0, "Received Route Query for src %s grp %s notification %d", inet_fmt(route_query->source_addr.s_addr, s1), inet_fmt(route_query->dest_addr.s_addr,s2), BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT)); /* Send Route Reply to client */ rsrr_accept_rq(route_query,rsrr->flags,NULL); break; default: logit(LOG_WARNING, 0, "Received RSRR packet type %d, which I don't handle", rsrr->type); break; } break; default: logit(LOG_WARNING, 0, "Received RSRR packet version %d, which I don't understand", rsrr->version); break; } }