keepalived-1.2.2单播补丁
2012-06-08 16:50:27 来源: 评论:0 点击:
分享一下Keepalived 1.2.2的单播补丁,基于Willy Tarreau patch早期版本的。早期版本可以在这里下载:http://1wt.eu/keepalived/ 早期...
分享一下Keepalived 1.2.2的单播补丁,基于Willy Tarreau patch早期版本的。 早期版本可以在这里下载: http://1wt.eu/keepalived/
早期补丁: http://1wt.eu/keepalived/keepalived-1.1.19-unicast.patch. 注意,因为本身并不C程序员,请评估下面的代码再考虑是否打这个补丁。显然这个补丁并不是RFC兼容的。但对于大型网络及组播不可用的环境而言,这个补丁去是非常重要的。 此补丁补充增加了2个参数: vrrp_unicast_bind vrrp_unicast_peer 当前补丁仅支持IPV4协议。 diff --git a/keepalived/include/vrrp.h b/keepalived/include/vrrp.h index 03c94f9..8c3cb15 100644 --- a/keepalived/include/vrrp.h +++ b/keepalived/include/vrrp.h @@ -94,6 +94,8 @@ typedef struct _vrrp_rt { list track_ifp; /* Interface state we monitor */ list track_script; /* Script state we monitor */ uint32_t mcast_saddr; /* Src IP address to use in VRRP IP header */ + uint32_t unicast_bind; /* listen to this IP if mcast is not possible */ + uint32_t unicast_peer; /* send to this IP if mcast is not possible */ char *lvs_syncd_if; /* handle LVS sync daemon state using this * instance FSM & running on specific interface * => eth0 for example. @@ -210,8 +212,8 @@ typedef struct _vrrp_rt { /* prototypes */ extern vrrp_pkt *vrrp_get_header(sa_family_t, char *, int *, uint32_t *); -extern int open_vrrp_send_socket(sa_family_t, int, int); -extern int open_vrrp_socket(sa_family_t, int, int); +extern int open_vrrp_send_socket(sa_family_t, int, int, int); +extern int open_vrrp_socket(sa_family_t, int, int, int); extern int new_vrrp_socket(vrrp_rt *); extern void close_vrrp_socket(vrrp_rt *); extern void vrrp_send_link_update(vrrp_rt *); diff --git a/keepalived/include/vrrp_if.h b/keepalived/include/vrrp_if.h index a17f9b2..2c62d60 100644 --- a/keepalived/include/vrrp_if.h +++ b/keepalived/include/vrrp_if.h @@ -117,7 +117,7 @@ extern void init_interface_linkbeat(void); extern void free_interface_queue(void); extern void dump_if(void *); extern int if_join_vrrp_group(sa_family_t, int *, interface *, int); -extern int if_leave_vrrp_group(sa_family_t, int, interface *); +extern int if_leave_vrrp_group(sa_family_t, int, interface *, int); extern int if_setsockopt_bindtodevice(int *, interface *); extern int if_setsockopt_hdrincl(int *); extern int if_setsockopt_mcast_loop(sa_family_t, int *); diff --git a/keepalived/vrrp/vrrp.c b/keepalived/vrrp/vrrp.c index b52c42c..dc8d180 100644 --- a/keepalived/vrrp/vrrp.c +++ b/keepalived/vrrp/vrrp.c @@ -385,8 +385,8 @@ vrrp_build_ip(vrrp_rt * vrrp, char *buffer, int buflen) /* fill protocol type --rfc2402.2 */ ip->protocol = (vrrp->auth_type == VRRP_AUTH_AH) ? IPPROTO_IPSEC_AH : IPPROTO_VRRP; - ip->saddr = VRRP_PKT_SADDR(vrrp); - ip->daddr = htonl(INADDR_VRRP_GROUP); + ip->saddr = vrrp->unicast_bind ? vrrp->unicast_bind : VRRP_PKT_SADDR(vrrp); + ip->daddr = vrrp->unicast_peer ? vrrp->unicast_peer : htonl(INADDR_VRRP_GROUP); /* checksum must be done last */ ip->check = in_csum((u_short *) ip, ip->ihl * 4, 0); @@ -582,7 +582,7 @@ vrrp_send_pkt(vrrp_rt * vrrp) if (vrrp->family == AF_INET) { memset(&dst4, 0, sizeof(dst4)); dst4.sin_family = AF_INET; - dst4.sin_addr.s_addr = htonl(INADDR_VRRP_GROUP); + dst4.sin_addr.s_addr = vrrp->unicast_peer ? vrrp->unicast_peer : htonl(INADDR_VRRP_GROUP); msg.msg_name = &dst4; msg.msg_namelen = sizeof(dst4); @@ -992,7 +992,7 @@ chk_min_cfg(vrrp_rt * vrrp) /* open a VRRP sending socket */ int -open_vrrp_send_socket(sa_family_t family, int proto, int idx) +open_vrrp_send_socket(sa_family_t family, int proto, int idx, int unicast) { interface *ifp; int fd = -1; @@ -1011,16 +1011,10 @@ open_vrrp_send_socket(sa_family_t family, int proto, int idx) /* Set v4 related */ if_setsockopt_hdrincl(&fd); if_setsockopt_bindtodevice(&fd, ifp); - if_setsockopt_mcast_loop(family, &fd); - if (fd < 0) - return -1; } else if (family == AF_INET6) { /* Set v6 related */ if_setsockopt_mcast_hops(family, &fd); if_setsockopt_mcast_if(family, &fd, ifp); - if_setsockopt_mcast_loop(family, &fd); - if (fd < 0) - return -1; } else { log_message(LOG_INFO, "cant open raw socket. unknow family=%d" , family); @@ -1028,12 +1022,17 @@ open_vrrp_send_socket(sa_family_t family, int proto, int idx) return -1; } + if (!unicast) + if_setsockopt_mcast_loop(family, &fd); + if (fd < 0) + return -1; + return fd; } /* open a VRRP socket and join the multicast group. */ int -open_vrrp_socket(sa_family_t family, int proto, int idx) +open_vrrp_socket(sa_family_t family, int proto, int idx, int unicast) { interface *ifp; int fd = -1; @@ -1050,7 +1049,8 @@ open_vrrp_socket(sa_family_t family, int proto, int idx) } /* Join the VRRP MCAST group */ - if_join_vrrp_group(family, &fd, ifp, proto); + if (!unicast) + if_join_vrrp_group(family, &fd, ifp, proto); if (fd < 0) return -1; @@ -1065,7 +1065,7 @@ open_vrrp_socket(sa_family_t family, int proto, int idx) void close_vrrp_socket(vrrp_rt * vrrp) { - if_leave_vrrp_group(vrrp->family, vrrp->fd_in, vrrp->ifp); + if_leave_vrrp_group(vrrp->family, vrrp->fd_in, vrrp->ifp, !vrrp->unicast_peer); close(vrrp->fd_out); } @@ -1079,8 +1079,8 @@ new_vrrp_socket(vrrp_rt * vrrp) close_vrrp_socket(vrrp); remove_vrrp_fd_bucket(vrrp); proto = (vrrp->auth_type == VRRP_AUTH_AH) ? IPPROTO_IPSEC_AH : IPPROTO_VRRP; - vrrp->fd_in = open_vrrp_socket(vrrp->family, proto, IF_INDEX(vrrp->ifp)); - vrrp->fd_out = open_vrrp_send_socket(vrrp->family, proto, IF_INDEX(vrrp->ifp)); + vrrp->fd_in = open_vrrp_socket(vrrp->family, proto, IF_INDEX(vrrp->ifp), !vrrp->unicast_peer); + vrrp->fd_out = open_vrrp_send_socket(vrrp->family, proto, IF_INDEX(vrrp->ifp), !vrrp->unicast_peer); alloc_vrrp_fd_bucket(vrrp); /* Sync the other desc */ diff --git a/keepalived/vrrp/vrrp_data.c b/keepalived/vrrp/vrrp_data.c index 3725f95..51ee552 100644 --- a/keepalived/vrrp/vrrp_data.c +++ b/keepalived/vrrp/vrrp_data.c @@ -139,7 +139,7 @@ free_sock(void *sock_data) interface *ifp; if (sock->fd_in > 0) { ifp = if_get_by_ifindex(sock->ifindex); - if_leave_vrrp_group(sock->family, sock->fd_in, ifp); + if_leave_vrrp_group(sock->family, sock->fd_in, ifp, 0); } if (sock->fd_out > 0) close(sock->fd_out); diff --git a/keepalived/vrrp/vrrp_if.c b/keepalived/vrrp/vrrp_if.c index a4c55e7..3da4cec 100644 --- a/keepalived/vrrp/vrrp_if.c +++ b/keepalived/vrrp/vrrp_if.c @@ -461,7 +461,7 @@ if_join_vrrp_group(sa_family_t family, int *sd, interface *ifp, int proto) } int -if_leave_vrrp_group(sa_family_t family, int sd, interface *ifp) +if_leave_vrrp_group(sa_family_t family, int sd, interface *ifp, int unicast) { struct ip_mreqn imr; struct ipv6_mreq imr6; @@ -471,6 +471,9 @@ if_leave_vrrp_group(sa_family_t family, int sd, interface *ifp) if (sd < 0 || !ifp) return -1; + if (unicast) + goto skip_mcast_release; + /* Leaving the VRRP multicast group */ if (family == AF_INET) { memset(&imr, 0, sizeof(imr)); @@ -499,6 +502,7 @@ if_leave_vrrp_group(sa_family_t family, int sd, interface *ifp) return -1; } +skip_mcast_release: /* Finally close the desc */ close(sd); return 0; diff --git a/keepalived/vrrp/vrrp_parser.c b/keepalived/vrrp/vrrp_parser.c index 5888723..26fb069 100644 --- a/keepalived/vrrp/vrrp_parser.c +++ b/keepalived/vrrp/vrrp_parser.c @@ -154,6 +154,18 @@ vrrp_mcastip_handler(vector strvec) inet_ston(VECTOR_SLOT(strvec, 1), &vrrp->mcast_saddr); } static void +vrrp_unicast_bind_handler(vector strvec) +{ + vrrp_rt *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); + inet_ston(VECTOR_SLOT(strvec, 1), &vrrp->unicast_bind); +} +static void +vrrp_unicast_peer_handler(vector strvec) +{ + vrrp_rt *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); + inet_ston(VECTOR_SLOT(strvec, 1), &vrrp->unicast_peer); +} +static void vrrp_vrid_handler(vector strvec) { vrrp_rt *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); @@ -431,6 +443,8 @@ vrrp_init_keywords(void) install_keyword("track_interface", &vrrp_track_int_handler); install_keyword("track_script", &vrrp_track_scr_handler); install_keyword("mcast_src_ip", &vrrp_mcastip_handler); + install_keyword("vrrp_unicast_bind", &vrrp_unicast_bind_handler); + install_keyword("vrrp_unicast_peer", &vrrp_unicast_peer_handler); install_keyword("virtual_router_id", &vrrp_vrid_handler); install_keyword("priority", &vrrp_prio_handler); install_keyword("advert_int", &vrrp_adv_handler); diff --git a/keepalived/vrrp/vrrp_scheduler.c b/keepalived/vrrp/vrrp_scheduler.c index 53d514d..ffef10c 100644 --- a/keepalived/vrrp/vrrp_scheduler.c +++ b/keepalived/vrrp/vrrp_scheduler.c @@ -469,12 +469,12 @@ vrrp_open_sockpool(list l) for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { sock = ELEMENT_DATA(e); sock->fd_in = open_vrrp_socket(sock->family, sock->proto, - sock->ifindex); + sock->ifindex, 0); if (sock->fd_in == -1) sock->fd_out = -1; else sock->fd_out = open_vrrp_send_socket(sock->family, sock->proto, - sock->ifindex); + sock->ifindex, 0); } }
相关热词搜索:keepalived unicast 补丁
上一篇:第一页
下一篇:智能DNS解析与用户定位调度技术
分享到:
收藏
![分享到腾讯微博](http://v.t.qq.com/share/images/s/weiboicon16.png)