ospfd Point-to-Multipoint support
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 5b63a76..6d7af05 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -589,6 +589,44 @@
 
 #define lsa_link_nbma_set(S,O)  lsa_link_broadcast_set (S, O)
 
+/* this function add for support point-to-multipoint ,see rfc2328 
+12.4.1.4.*/
+/* from "edward rrr" <edward_rrr@hotmail.com>
+   http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
+int lsa_link_ptomultip_set (struct stream *s, struct ospf_interface *oi)
+{
+  int links = 0;
+  struct route_node *rn;
+  struct ospf_neighbor *nbr = NULL;
+  struct in_addr id, mask;
+
+  mask.s_addr = 0xffffffff;
+  id.s_addr = oi->address->u.prefix4.s_addr;
+  link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
+  links++;
+
+  zlog_info ("PointToMultipoint: running ptomultip_set");
+
+  /* Search neighbor, */
+  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
+    if ((nbr = rn->info) != NULL)
+      /* Ignore myself. */
+      if (!IPV4_ADDR_SAME (&nbr->router_id, &ospf_top->router_id))
+	if (nbr->state == NSM_Full)
+
+	  {
+	    
+	    link_info_set (s, nbr->router_id, oi->address->u.prefix4,
+			   LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost);
+	    links++;
+	    zlog_info ("PointToMultipoint: set link to %s",
+		       inet_ntoa(oi->address->u.prefix4));
+	  }
+  
+  return links;
+  
+}
+
 /* Set router-LSA link information. */
 int
 router_lsa_link_set (struct stream *s, struct ospf_area *area)
@@ -619,7 +657,7 @@
 		  links += lsa_link_nbma_set (s, oi);
 		  break;
 		case OSPF_IFTYPE_POINTOMULTIPOINT:
-		  /* Not supproted yet. */
+		  links += lsa_link_ptomultip_set (s, oi);
 		  break;
 		case OSPF_IFTYPE_VIRTUALLINK:
 		  links += lsa_link_virtuallink_set (s, oi);
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 62b93fe..d2338ff 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -3137,6 +3137,8 @@
   else if ((oi->type == OSPF_IFTYPE_POINTOPOINT) 
 	   && (flag == OSPF_SEND_PACKET_INDIRECT))
      p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
+  else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
+     p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
   else
      p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
 
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index d625471..6e92bb2 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -365,18 +365,39 @@
 	      
 	      if (l->m[0].type == LSA_LINK_TYPE_POINTOPOINT)
 		{
-		  while ((l2 = ospf_get_next_link (w, v, l2)))
+		  /* check for PtMP, signified by PtP link V->W with link_data our PtMP interface */
+                  oi = ospf_if_is_configured(&l->link_data);
+                  if (oi && oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
 		    {
-		      oi = ospf_if_is_configured (&(l2->link_data));
+		    
+		      struct prefix_ipv4 * la = prefix_ipv4_new();
+		      la->prefixlen = oi->address->prefixlen;
 		      
-		      if (oi == NULL)
-			continue;
-		      
-		      if (! IPV4_ADDR_SAME (&oi->address->u.prefix4,
-					    &l->link_data))
-			continue;
-		      
-		      break;
+		      /* we link to them on PtMP interface - find the interface on w */
+		      while ((l2 = ospf_get_next_link (w, v, l2)))
+			{
+			  la->prefix = l2->link_data;
+			  
+			  if (prefix_cmp((struct prefix *)la, oi->address) == 0)
+			    /* link_data is on our PtMP network */
+			    break;
+			  
+			}
+		    }
+		  else
+		    {                                
+		      while ((l2 = ospf_get_next_link (w, v, l2)))
+			{
+			  oi = ospf_if_is_configured (&(l2->link_data));
+			  
+			  if (oi == NULL)
+			    continue;
+			  
+			  if (!IPV4_ADDR_SAME (&oi->address->u.prefix4, &l->link_data))
+			    continue;
+			  
+			  break;
+                      }
 		    }
 		  
 		  if (oi && l2)