#include #ifdef MPLS_LINUX #include #endif #include #include #include #include #include #include #include #include #include "ldp_struct.h" #include "ldp_entity.h" #include "ldp_mpls_impl.h" #include "ldp_socket_impl.h" static int label = 16; extern int _netlink_fd; ldp_bool ldp_mpls_handle_verify(ldp_mpls_handle handle) { return LDP_TRUE; } ldp_mpls_handle ldp_mpls_open(ldp_instance_handle user_data) { return socket(AF_INET,SOCK_STREAM,0); } void ldp_mpls_close(ldp_mpls_handle handle) { close(handle); } ldp_return_enum ldp_mpls_outlabel_add(ldp_mpls_handle handle,ldp_outlabel* o) { #ifdef MPLS_LINUX struct mpls_out_label_req oreq; oreq.mol_label.ml_type = MPLS_LABEL_GEN; oreq.mol_label.u.ml_gen = o->l.u.gen; oreq.mol_ifindex = o->session->entity->p.iff->handle; oreq.mol_nh.sa_family = AF_INET; ((struct sockaddr_in*)(&oreq.mol_nh))->sin_addr.s_addr = htonl(o->session->adj->remote_source_address.u.ipv4); send_nhlfe(_netlink_fd,&oreq,RTM_NEWNHLFE); #endif return LDP_SUCCESS; } void ldp_mpls_outlabel_del(ldp_mpls_handle handle,ldp_outlabel* o) { #ifdef MPLS_LINUX struct mpls_out_label_req oreq; oreq.mol_label.ml_type = MPLS_LABEL_GEN; oreq.mol_label.u.ml_gen = o->l.u.gen; oreq.mol_ifindex = o->session->entity->p.iff->handle; oreq.mol_nh.sa_family = AF_INET; ((struct sockaddr_in*)(&oreq.mol_nh))->sin_addr.s_addr = htonl(o->session->adj->remote_source_address.u.ipv4); send_nhlfe(_netlink_fd,&oreq,RTM_DELNHLFE); #endif } ldp_return_enum ldp_mpls_inlabel_add(ldp_mpls_handle handle,ldp_inlabel* i) { #ifdef MPLS_LINUX struct mpls_in_label_req ireq; #endif if(i->l.type == LDP_LABEL_NONE) { i->l.type = LDP_LABEL_GEN; i->l.u.gen = label++; } #ifdef MPLS_LINUX ireq.mil_label.ml_type = MPLS_LABEL_GEN; ireq.mil_label.u.ml_gen = i->l.u.gen; ireq.mil_labelspace = i->label_space; send_ilm(_netlink_fd,&ireq,RTM_NEWILM); #endif return LDP_SUCCESS; } void ldp_mpls_inlabel_del(ldp_mpls_handle handle,ldp_inlabel* i) { #ifdef MPLS_LINUX struct mpls_in_label_req ireq; ireq.mil_label.ml_type = MPLS_LABEL_GEN; ireq.mil_label.u.ml_gen = i->l.u.gen; ireq.mil_labelspace = i->label_space; send_ilm(_netlink_fd,&ireq,RTM_DELILM); #endif } ldp_return_enum ldp_mpls_in2out_add(ldp_mpls_handle handle,ldp_inlabel* i, ldp_outlabel* o) { #ifdef MPLS_LINUX struct mpls_xconnect_req xreq; struct mpls_out_label_req oreq; struct mpls_in_label_req ireq; fprintf(stderr,"ldp_mpls_in2out_add: %d <-> %d\n",i->l.u.gen, o->l.u.gen); ireq.mil_label.ml_type = MPLS_LABEL_GEN; ireq.mil_label.u.ml_gen = i->l.u.gen; ireq.mil_labelspace = i->label_space; oreq.mol_label.ml_type = MPLS_LABEL_GEN; oreq.mol_label.u.ml_gen = o->l.u.gen; oreq.mol_ifindex = o->session->entity->p.iff->handle; oreq.mol_nh.sa_family = AF_INET; ((struct sockaddr_in*)(&oreq.mol_nh))->sin_addr.s_addr = htonl(o->session->adj->remote_source_address.u.ipv4); memcpy(&xreq.mx_in,&ireq.mil_label,sizeof(struct mpls_label)); memcpy(&xreq.mx_out,&oreq.mol_label,sizeof(struct mpls_label)); xreq.mx_ilabelspace = ireq.mil_labelspace; xreq.mx_oifindex = oreq.mol_ifindex; send_xc(_netlink_fd,&xreq,RTM_NEWXC); #endif return LDP_SUCCESS; } void ldp_mpls_in2out_del(ldp_mpls_handle handle,ldp_inlabel* i, ldp_outlabel* o) { #ifdef MPLS_LINUX struct mpls_xconnect_req xreq; struct mpls_out_label_req oreq; struct mpls_in_label_req ireq; fprintf(stderr,"ldp_mpls_in2out_del: %d <-> %d\n",i->l.u.gen, o->l.u.gen); ireq.mil_label.ml_type = MPLS_LABEL_GEN; ireq.mil_label.u.ml_gen = i->l.u.gen; ireq.mil_labelspace = i->label_space; oreq.mol_label.ml_type = MPLS_LABEL_GEN; oreq.mol_label.u.ml_gen = o->l.u.gen; oreq.mol_ifindex = o->session->entity->p.iff->handle; oreq.mol_nh.sa_family = AF_INET; ((struct sockaddr_in*)(&oreq.mol_nh))->sin_addr.s_addr = htonl(o->session->adj->remote_source_address.u.ipv4); memcpy(&xreq.mx_in,&ireq.mil_label,sizeof(struct mpls_label)); memcpy(&xreq.mx_out,&oreq.mol_label,sizeof(struct mpls_label)); xreq.mx_ilabelspace = ireq.mil_labelspace; xreq.mx_oifindex = oreq.mol_ifindex; send_xc(_netlink_fd,&xreq,RTM_DELXC); #endif } ldp_return_enum ldp_mpls_fec2out_add(ldp_mpls_handle handle,ldp_fec* f, ldp_outlabel* o) { #ifdef MPLS_LINUX struct mpls_bind_fec_req mbf_req; memset(&mbf_req,0,sizeof(struct mpls_bind_fec_req)); mbf_req.mbf_label.ml_type = MPLS_LABEL_GEN; mbf_req.mbf_label.u.ml_gen = o->l.u.gen; mbf_req.mbf_fec.prefix = htonl(f->prefix.u.ipv4); mbf_req.mbf_fec.len = f->prefix_len; mbf_req.mbf_ifindex = o->session->entity->p.iff->handle; fprintf(stderr,"FEC: %08x/%d\n",mbf_req.mbf_fec.prefix,mbf_req.mbf_fec.len); send_ftn(_netlink_fd,&mbf_req,RTM_NEWFTN); #endif return LDP_SUCCESS; } void ldp_mpls_fec2out_del(ldp_mpls_handle handle,ldp_fec* f,ldp_outlabel* o) { #ifdef MPLS_LINUX struct mpls_bind_fec_req mbf_req; memset(&mbf_req,0,sizeof(struct mpls_bind_fec_req)); mbf_req.mbf_label.ml_type = MPLS_LABEL_GEN; mbf_req.mbf_label.u.ml_gen = o->l.u.gen; mbf_req.mbf_fec.prefix = htonl(f->prefix.u.ipv4); mbf_req.mbf_fec.len = f->prefix_len; mbf_req.mbf_ifindex = o->session->entity->p.iff->handle; send_ftn(_netlink_fd,&mbf_req,RTM_DELFTN); #endif }