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解析与用户定位调度技术

分享到: 收藏
评论排行